/**
 *
 * 如果您不清楚本类的具体实现，状态管理，请不要修改代码，否则可能引起未知错误
 *
 * 解决获取服务列表函数调用失败的方案：
 * 1.正常流程获取
 * 2.正常流程获取失败后，重新连接一次,延迟10秒(数据库可配置)再次获取
 * 3.重新连接后仍没有获取成功，则根据数据库配置的桩的uuid直接进行操作;失败则记录日志
 * 4.获取服务数据丢包处理；在1秒(数据库可配置)内没有获得完成数据包，认为丢包，则重新发送指令获取数据;
 *   只对85,95命令做重试操作
 */

import EncryptUtil from '../utils/EncryptUtil';
import CRC16 from '../utils/CRC16';
var aesUtil = require("../utils/aes.js");

var ConstantData = require('constant_data.js')
var commonUtil = require('common.js')
var colonyBlue = require("../pages/index/colony_blue.js")


var Base64 = require('base64.js');

var a = getApp(),
  s = 3,
  c = 500,
  r = null,
  openAdapterCount = 3,
  openAdapterTime = 500;

var Status = {
  normal: 'normal', //初始状态
  appVersionNotSupported: 'appVersionNotSupported', //当前客户端版本不支持小程序蓝牙
  adapterOpening: 'adapterOpening', //蓝牙适配器正在打开
  adaperOpenSuccess: 'adaperOpenSuccess', //蓝牙适配器打开成功
  adaperOpenFail: 'adaperOpenFail', //蓝牙适配器打开失败
  adapterCloseing: 'adapterCloseing', //蓝牙适配器正在关闭
  adaperCloseSuccess: 'adaperCloseSuccess', //蓝牙适配器关闭成功
  adaperCloseFail: 'adaperCloseFail', //蓝牙适配器关闭失败
  bleIsClosed: 'bleIsClosed', //手机蓝牙已关闭（连接设备时回调一次）
  bleIsOpened: 'bleIsOpened', //手机蓝牙已打开（连接设备时回调一次）
  bleClosed: 'bleClosed', //手机蓝牙已关闭（状态动态变化）
  bleOpened: 'bleOpened', //手机蓝牙已打开（状态动态变化）
  bleScaning: 'bleScaning', //扫描蓝牙设备中
  bleScanStart: 'bleScanStart', //开始扫描蓝牙设备
  bleScanStop: 'bleScanStop', //停止扫描蓝牙设备
  bleScanFail: 'bleScanFail', //扫描蓝牙设备失败
  bleConnectSuccess: 'bleConnectSuccess', //连接蓝牙设备成功
  bleConnectFail: 'bleConnectFail', //连接蓝牙设备失败
  bleDisconnected: 'bleDisconnected', //当前连接的蓝牙设备异常断开
  bleReConnected: 'bleReConnected', //当前连接的蓝牙设备恢复连接
  bleNotSupportWXService: 'bleNotSupportWXService', //设备不支持微信协议服务
  bleSupportWXService: 'bleSupportWXService', //设备已支持微信协议服务
  bleNotSupportWXCharacteristic: 'bleNotSupportWXCharacteristic', //设备不支持微信协议特征
  bleSupportWXCharacteristic: 'bleSupportWXCharacteristic', //设备已支持微信协议特征
  bleReceiveData: 'bleReceiveData', //设备开始接收数据
  bleConnectTimeout: 'bleConnectTimeout', //连接设备超时
  bleReceiveAuthData: 'bleReceiveAuthData', //接收请求授权数据状态
  bleReceiveInitData: 'bleReceiveInitData', //接收请求初始化数据状态
  bleReceiveBaseData: 'bleReceiveBaseData', //接收普通数据状态
  bleInitSuccess: 'bleInitSuccess', //设备连接成功（95指令已发送并解析成功），可以发送85指令了
  ble85Back1Timeout: 'ble85Back1Timeout', //85回执1超时
  ble85Back2Timeout: 'ble85Back2Timeout', //85回执2超时
  bleSend85Timeout: 'bleSend85Timeout', //发送85超时
  bleSend95Timeout: 'bleSend95Timeout', //发送95超时
  bleRecive95Timeout: 'bleRecive95Timeout', //95数据超时
  bleReciveAuto95Timeout: 'bleReciveAuto95Timeout', //auto95数据超时
  bleSend95ConDis: 'bleSend95ConDis', //发送95时蓝牙断开
  bleSend95DevNull: 'bleSend95DevNull', //发送95时设备信息空
  bleRecive75Timeout: 'bleRecive75Timeout', //75数据超时
  bleRecive75NTimeout: 'bleRecive75NTimeout', //75第N包数据超时
  bleRecive76Timeout: 'bleRecive76Timeout', //76数据超时
  bleSend98Timeout: 'bleSend98Timeout', //发送95超时
  bleSendB0Timeout: 'bleSendB0Timeout', //发送B0超时
  bleSendBaseTimeout: 'bleSendBaseTimeout', //发送Base超时
  bleReciveOneMorePhyTokenTimeout: 'bleReciveOneMorePhyTokenTimeout', //陪护椅one more获取token超时
  bleSendOneMorePhyUnlockTimeout: 'bleSendOneMorePhyUnlockTimeout', //one more陪护椅发送开锁指令超时
  ble85Data: 'ble85Data', //已收到85数据
  ble95Data: 'ble95Data', //已收到95数据
  ble98Data: 'ble98Data', //已收到95数据
  ble88Data: 'ble88Data', //已收到95数据
  ble1301Data: 'ble1301Data', //已收到95数据
  ble01Data: 'ble01Data', //已收到01数据，即随机数数据
  ble75zeroData: 'ble75zeroData', //已收到75第0包的数据
  ble75NData: 'ble75NData', //已收到75第N包的数据
  ble76Data: 'ble76Data', //已收到76返回的数据
  bleOneMorePhyLockStatusData: 'bleOneMorePhyLockStatusData', //one more 陪护椅锁状态数据
  bleOneMorePhyUnLockData: 'bleOneMorePhyUnLockData', //one more 陪护椅开锁的结果数据
  bleOneMorePhyLockBattery: 'bleOneMorePhyLockBattery', //one more陪护椅电量值
}

var _ConnectTimeout = null //连接超时
var _ConnectTimeoutSize = 25 //连接超时时间（单位秒）
var _CreateConnectionTimeoutSize = 5000 // 创建连接的api超时时间单位毫秒

var directConTimeoutSeconds = 15; //直连连接超时
var timer_directCon_seconds = null;

var _adapterFailTimeSize = 5 //初始化蓝牙适配器超时未执行
var _adapterFailTimer = null //定时器

var _noLocationAuthTimeSize = 10 //无位置授权的超时时间
var _noLocationAuthFlg = true //默认无位置权限，搜索到蓝牙设备后设置为false（有位置权限）
var _noLocationAuthTimer = null //定时器

var _SendCommandTimeout = null //发送指令超时（指令发送成功，并收到设备的指令响应数据，否则超时）
var _SendCommandTimeoutSize = 5 //发送指令超时时间（单位秒）
var _85Back1TimeoutSize = 15 //85第1次回执超时时间
var _85Back1Timeout = null
var _85Back2TimeoutSize = 20 //85第2次回执超时时间
var _85Back2Timeout = null

var _IsScaning = false //是否正在搜索设备
var _Status = Status.normal //当前状态
var _DeviceName = null //当前请求连接的设备名称
var _Callback = null //状态监听回调
var _ErrorLog = null //错误日志记录回调
var _ConnectLog = null //蓝牙连接日志记录回调
var _Device = null //当前请求连接的设备对象
var _scanBoxFlg = false; //true只扫描不连接
var _WXServiceUUID = null //微信协议服务的UUID
var _WXIndicateUUID = null //微信协议Indicate特征的UUID
var _WXWriteUUID = null //微信协议Write特征的UUID
var _WXReadUUID = null //微信协议Read特征的UUID
var _RetryCount = 0 //第几次重新连接设备
var _AuthString = null //设备发来的完整授权数据
var _AuthMD5 = null //授权数据中的MD5值大写，md5（deviceType + deviceId）
var _AuthSize = 0 //完整授权数据长度
var _InitString = null //设备发来的完整初始化数据
var _InitSize = 0 //完整初始化数据长度
var _RandomNumKey = ''; //新固件驱动上传的随机数
var _Version = '01'; //驱动协议
var _DataString = null //设备发来的普通数据
var _DataSize = 0 //普通数据长度
var _IsBLEOpened = false //当前手机蓝牙是否已打开
var _Data85 = null //解析后的85数据
var _Data88 = null //解析后的85数据
var _Data95 = null //解析后的95数据
var _Data98 = null //解析后的95数据
var _Data75Zero = null //解析后的格子柜75第0包的数据
var _Data75N = null // 解析后的格子柜的第N包数据
var _Data76 = null //解析后的格子柜开锁结果的数据
var _DataOneMorePhyLockStatusData = null; //one more陪护椅锁状态数据
var _DataOneMorePhyUnLockData = null; //one more陪护椅开锁结果数据
var _DataOneMorePhyLockBattery = null; //one more陪护椅锁电量值
var _Data1301 = null //解析后的95数据
var _IsFirstConnected = false //是否已经首次连接成功过
var _curConIsCache = false; //是否通过设备缓存进行的连接，true是，false不是
var _ServerConfigInfo = {
  connectDelayed: {
    openBluetoothAdapter: 100,
    startBluetoothDevicesDiscovery: 300,
    getBLEDeviceServices: 300,
    getBLEDeviceCharacteristics: 1500,
    failGetBLEDeviceServices: 300,
    failGetBLEDeviceCharacteristics: 1000,
    writeData: 100
  }
}; //服务配置信息

var _serviceUUID = ''
var _fec7 = ''
var _fec8 = ''
var _fec9 = ''
var _CollectionServiceInfo = null; //收集桩的服务信息

var _getBLEDeviceServicesDelayTime = 10000 //重新连接后再次获取服务列表的延迟时间
var _getBLEDeviceServiesRetryConCount = 0 //获取服务列表重连次数
var _currBlueConStage = '' //当前蓝牙连接的阶段
var _isOpenAdapterFlg = false //是否打开了适配器，用于判断是否调用关闭适配器,false没有打开,true打开了
var _reqId = null;
var _EncryptValue = null
var _TimeBytes = null
var _that = null;

//是否中转85开锁指令为88开锁指令
var _transferOpenLockCmd = true
//硬件软件驱动版本号
var _driverVersion = null
var _BaseDataCallBack = null
//接收到的广播数据
var broadcastDevList = {};
//接收到的广播数据缓存
var broadcastDevListCache = {};
var _allowDuplicatesKey = true; //是否允许重复上报同一设备。如果允许重复上报，则 wx.onBlueToothDeviceFound 方法会多次上报同一设备，但是 RSSI 值会有不同。

function setServerConfigInfo(config) {

  console.log("【设置服务器配置信息】", config)

  if (config != null && config != undefined) {
    _ServerConfigInfo = config
    if (config.connectTimeOut) {
      _ConnectTimeoutSize = config.connectTimeOut
      //给获取服务列表延迟时间赋值
      _getBLEDeviceServicesDelayTime = _ServerConfigInfo.connectDelayed.reGetBLEDeviceServices
    }
  }
}

function setIsOpenAdapterFlg(flg) {
  _isOpenAdapterFlg = flg;
}

//设置归位桩的服务id信息
function setHomingDeviceServiceInfo(uuid, fec7, fec8, fec9) {

  console.log("【设置设备蓝牙服务信息】", uuid, fec7, fec8, fec9)

  _serviceUUID = uuid
  _fec7 = fec7
  _fec8 = fec8
  _fec9 = fec9

}
//设置连接超时时间
function setConnectiTimeOut(timeout) {

  console.log("【设置设备连接超时时间】", timeout)

  _ConnectTimeoutSize = timeout
}

//状态变化
function statusChanged(status) {

  console.log("【蓝牙管理器状态变化】", status, _Data85, _Callback)

  if (_Status == Status.bleConnectTimeout) {
    console.log("【蓝牙连接失败】设备连接超时...")
    _IsFirstConnected = true
    getApp().globalData.connect_stat = 'fail';
  }

  if (status == Status.bleInitSuccess ||
    status == Status.appVersionNotSupported ||
    status == Status.bleIsClosed ||
    status == Status.bleClosed ||
    status == Status.adaperOpenFail ||
    status == Status.bleNotSupportWXService ||
    status == Status.bleNotSupportWXCharacteristic) {
    stopTimeout()
  }

  if (status == Status.ble85Data ||
    status == Status.ble95Data || status == Status.ble98Data || status == Status.ble88Data) {
    stopTimeout()
    stopSendCommandTimeout()
  }
  if (status == Status.ble85Data || status == Status.ble88Data) {
    stop85Back1Timeout()
    if (_Data85 && _Data85.backSeq == 2) {
      stop85Back2Timeout()
    }
  }
  if (status == Status.ble75zeroData) {
    //TODO 格子柜75第0包的数据，总设备相关信息
  }
  if (status == Status.ble75zeroData) {
    //TODO 格子柜75第N包的数据，每个门的状态，根据总设备的信息获取几个门
  }

  _Status = status
  if (!_Callback) {
    let that = getApp().globalData._that;
    _Callback = that ? that.handleStatus : null;
    if (status == Status.adapterCloseing || status == Status.adaperCloseSuccess || status == Status.normal) {} else {
      commonUtil.recordErrorInfo(ConstantData.err_type.data_callback_null, "status=" + status + ",cabackIsNull 重新赋值");
    }
  }

  if (status == Status.ble88Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    let data88 = _Data88;
    _Callback(status, data88);
    _Data88 = '';
  } else if (status == Status.ble85Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data85)
  } else if (status == Status.ble95Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data95)
  } else if (status == Status.ble1301Data && _Callback != null) {
    console.log('我想看看这里有没有1301：', status)
    console.log('我想看看这里有没有1301：', _Data1301)
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data1301)
  } else if (status == Status.ble98Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data98)
  } else if (status == Status.ble75zeroData && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data75Zero)
  } else if (status == Status.ble75NData && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data75N)
  } else if (status == Status.ble76Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data76)
  } else if (status == Status.bleOneMorePhyLockStatusData && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _DataOneMorePhyLockStatusData)
  } else if (status == Status.bleOneMorePhyUnLockData && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _DataOneMorePhyUnLockData)
  } else if (status == Status.bleOneMorePhyLockBattery && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _DataOneMorePhyLockBattery);
  } else if (status == Status.ble01Data && _Callback != null) {
    //停止连接超时的计时
    // stopTimeout();
    statusChanged(Status.bleReceiveData)
    _Callback(status, _RandomNumKey)
  } else if (_Callback != null) {
    _Callback(status, null)
  } else {
    commonUtil.recordErrorInfo(ConstantData.err_type.data_callback_null_err, "status=" + status + ",cabackIsNull未做处理");
  }

}

//重置状态
function reset(callback, resetType) {
  if (_Device != null) {
    //尝试一次断开当前已连接的设备
    let devName = _Device.name;
    console.log("【正在尝试断开设备】" + devName)

    wx.closeBLEConnection({
      deviceId: _Device.deviceId,
      success: function (res) {
        console.log("【断开设备成功】", res)
        resetParams(callback)
      },
      fail: function (res) {
        console.error("【error】【wx.closeBLEConnection】【断开设备失败】" + devName, res)
        resetParams(callback)
      }
    })
  } else {
    resetParams(callback)
  }
}

//启动超时机制 目前只有旧连接在用，但是线上已经没有旧连接了，此处更改此函数,用于新连接
function startTimeout() {
  console.log("【开启蓝牙连接超时机制】", _ConnectTimeoutSize)
  stopTimeout()

  _ConnectTimeout = setTimeout(function () {
    //连接超时取消掉缓存连接，再次连接改用扫描连接
    if (_curConIsCache) {
      wx.setStorageSync('conIsUseCache', false);
    }

    showDialog("bleConnectTimeout", Status.bleConnectTimeout, function () {});
    console.error("【error】【bleConnectTimeout】【蓝牙连接失败】设备连接超时...")

  }, _ConnectTimeoutSize * 1000)

  a.globalData.timeoutConnectTimeout = _ConnectTimeout
  
}

//停止超时机制
function stopTimeout() {
  if (_ConnectTimeout != null) {
    clearTimeout(_ConnectTimeout)
    console.log("【关闭蓝牙连接超时机制】")
  }
  _ConnectTimeout = null
}

//启动蓝牙适配器初始化超时机制
function startOpenAdapterTimeout() {
  _that = _that ? _that : getApp().globalData._that

  stopOpenAdapterTimeout()

  console.log("启动蓝牙适配器初始化超时机制")

  _adapterFailTimer = setTimeout(() => {
    stopTimeout();
    stopLocationAuthTimeout();
    console.error("初始化蓝牙适配器超时未执行");
    showDialog("openAdapterTimeout", Status.bleConnectTimeout, function () {});
  }, 1000 * _adapterFailTimeSize)
}

//关闭适配器初始化超时机制
function stopOpenAdapterTimeout() {
  if (_adapterFailTimer != null) {
    clearTimeout(_adapterFailTimer)
    console.log("关闭适配器初始化超时机制")
  }
  _adapterFailTimer = null
}

//启动位置权限超时机制
//20200213 从代码来看此处的定时器，没有使用的地方，暂时不做调用，超时原因标注错误，已修改
function startLocationAuthTimeout() {
  _that = _that ? _that : getApp().globalData._that

  stopLocationAuthTimeout()

  console.log("启动位置授权超时机制")

  _noLocationAuthTimer = setTimeout(() => {
    stopTimeout();
    stopOpenAdapterTimeout()
    console.error("蓝牙搜索 超时未收到");
    //此处的弹框说明存在问题noDevicesFound
    showDialog("locationAuthTimeout", Status.bleConnectTimeout, function () {});
  }, 1000 * _noLocationAuthTimeSize)
}

//关闭位置权限超时机制
function stopLocationAuthTimeout() {
  if (_noLocationAuthTimer != null) {
    clearTimeout(_noLocationAuthTimer)
    console.log("关闭位置授权超时机制")
  }
  _noLocationAuthTimer = null
}

//启动发送指令超时机制
function startSendCommandTimeout(status) {

  console.log("【开启发送指令超时机制】", status)

  stopSendCommandTimeout()
  _SendCommandTimeout = setTimeout(function () {
    statusChanged(status)

    console.error("【error】【sendCommandTimeout】【发送指令超时】", status)

    thisDisconnect('发送指令超时：' + status)

  }, _SendCommandTimeoutSize * 1000)
}

//停止发送指令超时机制
function stopSendCommandTimeout() {
  if (_SendCommandTimeout != null) {
    clearTimeout(_SendCommandTimeout)
    console.log("【关闭发送指令超时机制】")
  }
  _SendCommandTimeout = null
}



//启动85回执1超时机制
function start85Back1Timeout(status) {

  console.log("【开启85回执1超时机制】", status)
  stop85Back1Timeout()

  _85Back1Timeout = setTimeout(function () {
    statusChanged(status)
    stop85Back2Timeout()

    console.error("【error】【85Back1Timeout】【85回执1超时】", status)
    let app = getApp()
    if (app.globalData._that && typeof app.globalData._that.getBleFailShowObj == 'function') {
      let failShow = app.globalData._that.getBleFailShowObj()
      failShow.openFailTipShow('')
    }

  }, _85Back1TimeoutSize * 1000)
}

//停止85回执1超时机制
function stop85Back1Timeout() {
  if (_85Back1Timeout != null) {
    clearTimeout(_85Back1Timeout)
    console.log("【关闭85回执1超时机制】")
  }
  _85Back1Timeout = null
}

//启动85回执2超时机制
function start85Back2Timeout(status) {

  console.log("【开启85回执2超时机制】", status)
  stop85Back2Timeout()

  _85Back2Timeout = setTimeout(function () {
    statusChanged(status)
    console.error("【error】【85Back2Timeout】【85回执2超时】", status)
    let app = getApp()
    if (app.globalData._that && typeof app.globalData._that.getBleFailShowObj == 'function') {
      let failShow = app.globalData._that.getBleFailShowObj()
      failShow.openFailTipShow('')
    }

  }, _85Back2TimeoutSize * 1000)
}

//停止85回执2超时机制
function stop85Back2Timeout() {
  if (_85Back2Timeout != null) {
    clearTimeout(_85Back2Timeout)
    console.log("【关闭85回执2超时机制】")
  }
  _85Back2Timeout = null
}


//收集设备服务信息
function setCollectionServiceData(callback) {
  console.log("【设置收集设备服务信息】")
  _CollectionServiceInfo = callback
}
//设置错误日志记录回调
function setErrorCallback(callback) {
  console.log("【设置错误日志记录回调】")
  _ErrorLog = callback
}

//设置错误日志记录回调
function setConnectLogCall(callback) {
  console.log("【设置连接错误日志记录回调】")
  _ConnectLog = callback
}

//重置具体参数
function resetParams(callback) {

  console.log("【重置默认参数】", callback == null ? 'callback is null' : 'callback not null')

  _IsScaning = false //是否正在搜索设备
  _Status = Status.normal //当前状态
  _DeviceName = null //当前请求连接的设备名称
  _Callback = null //状态监听回调
  _Device = null //当前请求连接的设备对象
  _scanBoxFlg = false;
  _WXServiceUUID = null //微信协议服务的UUID
  _WXIndicateUUID = null //微信协议Indicate特征的UUID
  _WXWriteUUID = null //微信协议Write特征的UUID
  _WXReadUUID = null //微信协议Read特征的UUID
  _AuthString = null //完整授权数据
  _AuthMD5 = null //授权数据中的MD5值大写，md5（deviceType + deviceId）
  _AuthSize = 0 //完整授权数据长度
  _InitString = null //设备发来的完整初始化数据
  _InitSize = 0 //完整初始化数据长度
  _RandomNumKey = ''; //新版驱动收取的随机数
  _Version = '01'; //驱动协议
  _DataString = null //设备发来的普通数据
  _DataSize = 0 //普通数据长度
  _IsBLEOpened = false //当前手机蓝牙是否已打开
  _Data85 = null //解析后的85数据
  _Data88 = null //解析后的85数据
  _Data95 = null //解析后的95数据
  _Data75Zero = null //解析后的格子柜75第0包的数据
  _Data75N = null // 解析后的格子柜的第N包数据
  _Data76 = null //解析后的格子柜开锁结果的数据
  _DataOneMorePhyLockStatusData = null; //one more陪护椅锁状态数据
  _DataOneMorePhyUnLockData = null; //one more陪护椅开锁结果数据
  _DataOneMorePhyLockBattery = null; //one more陪护椅锁电量值
  _Data1301 = null //解析后的95数据
  //是否中转85开锁指令为88开锁指令 2019-08-07 16:57直接是用88进行开锁
  _transferOpenLockCmd = true
  _driverVersion = null
  _BaseDataCallBack = null

  callback()

}

//尝试重新连接设备
function retryConnect(lineNum) {
  commonUtil.recordErrorInfo(ConstantData.err_type.ble_connect, "重试连接,lineNum:" + lineNum);
  if (a.globalData.consuc === true) {
    console.log("--已连接成功断开不做重试--");
    return;
  }
  if (getApp().globalData._that && getApp().globalData._that.data.openLockStat) {
    console.log("--开锁后不做重连");
    return;
  }
  _currBlueConStage = 'recon' + _RetryCount
  _RetryCount++

  console.log("【自动尝试重连设备...】：" + _RetryCount + "--" + lineNum)

  connect(_DeviceName, _Callback, _ConnectTimeoutSize, true, null)
}

//连接蓝牙，设备名称，状态监听回调
function connect(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  _RandomNumKey = '';
  _that = that ? that : getApp().globalData._that;
  _that.data.blepwd = '';

  if (encryptValue) {
    _EncryptValue = encryptValue;
  } else {
    _EncryptValue = null;
  }

  if (timeBytes) {
    _TimeBytes = timeBytes;
  } else {
    _TimeBytes = null;
  }

  if (!isRetry || isRetry == null || isRetry == undefined) {

    getApp().lajax.sendLog()

    _reqId = guid()

    getApp().lajax.setConnectInfo({
      conReqid: _reqId,
      conBleMac: deviceName,
    })

    getApp().lajax.resetConSort()

    getApp().lajax.setConRFID(null)

    console.log("【连接共享轮椅---起点】", _reqId, deviceName)

    _RetryCount = 0

    if (timeout > 0) {
      _ConnectTimeoutSize = timeout
    }

    startTimeout()

    _IsFirstConnected = false //是否已经首次连接成功过

    _currBlueConStage = 'firstCon'

  } else {
    console.log("【连接共享轮椅---重连】", _reqId, deviceName)
  }

  //重置状态
  reset(function () {
    _DeviceName = deviceName ? deviceName.toUpperCase() : "";
    _Callback = statusCallback

    //先尝试关闭一次蓝牙适配器，再延迟500毫秒打开蓝牙适配器
    closeBluetoothAdapter(function () {

      setTimeout(function () {
        openBluetoothAdapter(false);
      }, _ServerConfigInfo.connectDelayed.openBluetoothAdapter)

    })

  }, 'connect')

}

/**
 * 扫描上报设备信息
 */
function scanBox() {
  console.log("scanBox---broadcastDevListCache--->", broadcastDevListCache);
  console.log("scanBox---broadcastDevList--->", broadcastDevList);
  //不进行蓝牙连接将蓝牙连接的变量置空
  console.log('broadcastDevList------------------------------------->', broadcastDevList)
  _DeviceName = null;
  _scanBoxFlg = true;
  //注释掉使用自己的缓存机制
  _allowDuplicatesKey = false;
  //先尝试关闭一次蓝牙适配器，再延迟500毫秒打开蓝牙适配器
  closeBluetoothAdapter(function () {

    setTimeout(function () {
      openBluetoothAdapter(true)
    }, _ServerConfigInfo.connectDelayed.openBluetoothAdapter)

  })
}

//断开蓝牙连接
function disconnect(lineNum, stopConnect) {
  if (getApp().globalData.isOpenLock) {
    console.log("开锁中不断开蓝牙");
    return;
  }
  if (getApp().globalData.isUpgradeing) {
    console.log("升级中不进行蓝牙断开");
    return;
  }
  if (getApp().globalData._that && getApp().globalData._that.data.openLockStat) {
    console.log("--开锁中不断开蓝牙");
    return;
  }
  if (a.globalData.isConnecting === true && stopConnect != 'stopConnect') {
    console.log("--连接中不断开蓝牙");
    return;
  } else if (stopConnect == 'stopConnect') {
    stopTimeout();
    stopOpenAdapterTimeout();
    stopLocationAuthTimeout();
    stopSendCommandTimeout();
  }
  if(getApp().globalData.conNoticeTimer) {
    clearTimeout(getApp().globalData.conNoticeTimer)
  }
  console.warn("【UI层请求断开蓝牙连接】" + lineNum);

  getApp().globalData.disconnectLineNum = lineNum;

  if (getApp().globalData._that) {
    getApp().globalData._that.data.blepwd = null;
  }

  colonyBlue.gatewayDisCon(getApp().globalData._that, lineNum);

  _RetryCount = 0
  //执行断开操作
  executeDisconnect();

}

/**
 * 执行蓝牙断开的操作
 */
function executeDisconnect() {

  reset(function () {

    stopTimeout();
    wx.getConnectedBluetoothDevices({
      success: function (res) {
        let conDevices = res.devices;
        if (conDevices && conDevices.length > 0) {
          conDevices.forEach((item, index, array) => {
            //关闭已存在的连接
            let deviceId = item.deviceId;
            if (deviceId) {
              wx.closeBLEConnection({
                deviceId: deviceId,
                success: function (res) {},
                fail: function (err) {}
              });
            }
          });
          //关闭适配器
          setTimeout(function () {
            closeBluetoothAdapter(null);
          }, 300);
        } else {
          closeBluetoothAdapter(null);
        }
      },
      fail: function (err) {
        closeBluetoothAdapter(null);
      }
    });

  }, 'disconnect');

}

//断开蓝牙连接
function thisDisconnect(info) {
  if (a.globalData.isConnecting === true) {
    console.log("--连接中不断开蓝牙--thisDisconnect");
    return;
  }
  console.warn("【BLELocker层请求断开连接】" + info);

  //关闭心跳定时器
  if (getApp().globalData._that) {
    clearInterval(getApp().globalData._that.data.bleHeartTimer);
  }

  _RetryCount = 0
  //执行断开连接操作
  executeDisconnect();
}

//打开蓝牙适配器
function openBluetoothAdapter(isScan) {
  console.log("【正在打开蓝牙适配器】")

  _currBlueConStage = 'openBleAdapter'

  if (wx.openBluetoothAdapter) {

    wx.openBluetoothAdapter({
      success: function (res) {
        _isOpenAdapterFlg = true

        wx.removeStorageSync('retryOpenBlueAdapterCount');
        statusChanged(Status.adaperOpenSuccess)

        console.log("【打开蓝牙适配器成功】", res)

        //检测手机蓝牙是否开启
        checkBLEStatus(function () {

          //监听蓝牙适配器状态变化
          onBluetoothAdapterStateChange()

          if (isScan) {
            //开始扫描蓝牙设备
            setTimeout(function () {
              startBluetoothDevicesDiscovery()
            }, _ServerConfigInfo.connectDelayed.startBluetoothDevicesDiscovery)
          }

        })

      },
      fail: function (res) {
        if (_that) {
          _that.recordBlueConnectError(40020, 'openBluetoothAdapter fail:' + JSON.stringify(res));
        }
        a.globalData.conErrDesc = 'OLD:openBluetoothAdapter fail:' + JSON.stringify(res);
        if (res.errCode == 10001 || res.errMsg.indexOf('not available') != -1) {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(res), Status.bleIsClosed, function () {});
        } else {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(res), Status.adaperOpenFail, function () {});
        }
        console.error("【error】【wx.openBluetoothAdapter】【打开蓝牙适配器失败】", res)
      }
    })


  } else {
    statusChanged(Status.appVersionNotSupported)

    console.error("【error】【appVersionNotSupported】【当前客户端版本不支持小程序蓝牙...(001)】")

  }
}

//检测手机蓝牙是否开启
function checkBLEStatus(callback) {

  console.log("【正在获取蓝牙适配器状态】")

  _currBlueConStage = 'checkBleStatus'

  wx.getBluetoothAdapterState({
    success: function (res) {

      console.log("【获取蓝牙适配器状态成功】", res)

      if (res.available) {

        statusChanged(Status.bleIsOpened)

        console.log("【当前手机蓝牙已打开】")

        _IsBLEOpened = true

        if (res.discovering) {

          console.log("【当前正在扫描蓝牙设备】")

          console.log("【开始停止扫描蓝牙设备】")

          wx.stopBluetoothDevicesDiscovery({
            success: function (res) {
              statusChanged(Status.bleScanStop)

              console.log("【停止扫描蓝牙设备成功】", res)

              callback()
            },
            fail: function (res) {
              statusChanged(Status.bleScanStop)

              console.error("【error】【wx.stopBluetoothDevicesDiscovery】【停止扫描蓝牙设备失败】", res)

              callback()
            }
          })
        } else {

          callback()
        }

      } else {
        _IsBLEOpened = false
        statusChanged(Status.bleIsClosed)
        console.error("【error】【mobile not open ble】【手机蓝牙未打开】")
      }

    },
    fail: function (res) {
      console.error("【error】【wx.getBluetoothAdapterState】【获取蓝牙适配器状态失败】", res)
    }
  })
}

//关闭蓝牙适配器
function closeBluetoothAdapter(callback) {

  console.log("【请求关闭蓝牙适配器】")

  _currBlueConStage = 'closeBleAdapter'
  if (wx.closeBluetoothAdapter) {

    if (callback == null) {
      statusChanged(Status.adapterCloseing)
    }

    console.log("【正在关闭蓝牙适配器】")

    wx.closeBluetoothAdapter({
      success: function (res) {
        //适配器关闭成功
        _isOpenAdapterFlg = false
        if (callback == null) {
          statusChanged(Status.adaperCloseSuccess)
          console.log("【关闭蓝牙适配器成功】", res)

        } else {
          console.log("【关闭蓝牙适配器成功】", res)
        }
        statusChanged(Status.normal)

        console.log("【设备已恢复到初始状态（001）】")

      },
      fail: function (res) {
        if (callback == null) {
          statusChanged(Status.adaperCloseFail)
          console.error("【error】【wx.closeBluetoothAdapter】【关闭蓝牙适配器失败】", res)


        } else {
          console.error("【error】【wx.closeBluetoothAdapter】【关闭蓝牙适配器失败】", res)

        }

        statusChanged(Status.normal)

        console.log("【设备已恢复到初始状态（002）】")

      },
      complete: function () {

        console.log("【关闭蓝牙适配器完成】")

        if (callback != null) {
          callback()
        }

        getApp().lajax.setConRFID(null)

      }
    })
  } else {
    statusChanged(Status.appVersionNotSupported)

    console.error("【error】【appVersionNotSupported】当前客户端版本不支持小程序蓝牙...(002)")

    // //蓝牙连接日志
    // var logData = {
    //   reqNumber: 5,
    //   optDesc: "当前客户端版本不支持小程序蓝牙...(002)"
    // };
    // recordConnectLog(logData)

    getApp().lajax.setConRFID(null)

  }

}

//监听蓝牙适配器状态变化
function onBluetoothAdapterStateChange() {

  console.log("【开始监听蓝牙适配器状态变化】")

  _currBlueConStage = 'onAdapterStatChange'

  wx.onBluetoothAdapterStateChange(function (res) {
    console.log("【蓝牙适配器状态发生变化】", res)

    if (res.available == false) {
      if (_IsBLEOpened == true) {
        statusChanged(Status.bleClosed)
        console.log("【手动关闭蓝牙】")

      }
      _IsBLEOpened = false
    } else {
      if (_IsBLEOpened == false) {
        statusChanged(Status.bleOpened)
        console.log("【手动打开蓝牙】")
      }
      _IsBLEOpened = true
    }
  })

}

//开始扫描蓝牙设备
function startBluetoothDevicesDiscovery() {
  a.globalData.conErrDesc = 'OLD:开始扫描';
  console.log("【开始扫描蓝牙设备】")

  _currBlueConStage = 'startDiscoveryDev'

  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: true,
    powerLevel: 'high',
    // services: ['FEE7'],
    // interval: 1,
    success: function (res) {
      statusChanged(Status.bleScaning)
      console.log("【正在扫描蓝牙设备中】", res)

      _IsScaning = true

    },
    fail: function (res) {
      a.globalData.conErrDesc = 'OLD:startBluetoothDevicesDiscovery fail:' + JSON.stringify(res);
      console.error("【error】【wx.startBluetoothDevicesDiscovery】【扫描蓝牙设备失败】", res)
    }
  })

}

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  try {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
  } catch (ex) {
    return null;
  }
  return hexArr.join('');
}

function findDevStopDiscovery(pt) {
  console.log("【已匹配到请求连接的设备】", pt)

  //监听蓝牙设备连接状态变化
  if (pt === 'no_back_tip' || pt === 'lease_tip') {} else {
    onBLEConnectionStateChange()
  }

  console.log("【正在关闭蓝牙扫描】")
  _allowDuplicatesKey = true; //是否允许重复上报同一设备。如果允许重复上报，则 wx.onBlueToothDeviceFound 方法会多次上报同一设备，但是 RSSI 值会有不同。

  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      statusChanged(Status.bleScanStop)
      console.log("【关闭蓝牙扫描成功】", res)
      _IsScaning = false
      //开始上传扫描到的设备信息
      let rst = broadcastBack(pt);
      console.log("----扫描关闭成功--->", rst);
      if (pt === 'no_back_tip' || pt === 'lease_tip') {
        console.log("【关闭蓝牙适配器-网关归还的不进行适配器的关闭,防止卡点造成正常连接被关闭】..broadcastDevList=", broadcastDevList)
      } else if (rst === -1) {
        createBLEConnection('BLE989')
      }
    },
    fail: function (res) {
      //不管成功失败，扫描的设备均需要上报
      broadcastBack(pt);
      statusChanged(Status.bleScanStop)
      console.error("【error】【wx.stopBluetoothDevicesDiscovery】【关闭蓝牙扫描失败】", res)
      _IsScaning = false
      //连接已匹配的蓝牙设备
      createBLEConnection('BLE997')
    }
  })
  console.log("【正在关闭蓝牙扫描 end】")
}
/**
 * 广播归还未归还的设备
 */
function broadcastBack(pt, src) {
  let isAllowBroadcastBack = getApp().globalData.isAllowBroadcastBack;
  if (isAllowBroadcastBack == 0 || Object.keys(broadcastDevList).length == 0) {
    console.log("----不允许广播-----")
    if (src && src == 'con2') {
      connection(_that);
    } else if (src != 'nocon' && _scanBoxFlg === false) {
      createBLEConnection('BLE1012');
      return -2;
    }
    return -1;
  }

  console.log("broadcast-data:{}", broadcastDevList)
  let scanData = JSON.stringify(broadcastDevList);
  broadcastDevList = {}; //清空记录
  let upData = Base64.encode(scanData);
  let noBackRes = wx.getStorageSync("user_no_back");
  let equId = noBackRes && noBackRes.data.noBack ? noBackRes.data.noBack.equId : 0;
  let curTime = new Date().getTime();
  getApp().executeRequest(function (header) {

    wx.request({
      url: ConstantData.CONSTATNT_DATA.BASE_URL + '/broadcast/back',
      header: header,
      data: {
        data: upData,
        equId: equId,
        mac: _that ? _that.data.mac : ''
      },
      success: function (res) {
        console.log("花费的时长A:" + (new Date().getTime() - curTime));
        if (pt === 'lease_tip') {
          // disconnect('BLE1032');//200114 冯慧敏 取消断开连接，因为重置默认参数导致正常连接无法处理接收到的数据
          return;
        }
        if (res.data.data > 0) {
          disconnect('BLE1036');
          if (_that) {
            //关闭连接中的弹框
            _that.setData({
              loading_show: false,
              connectType: '租借'
            })
          }

          wx.removeStorageSync("user_no_back");
          if (res.data.data == 1) {
            let urlPre = pt === 'no_back_tip' ? ".." : "../index";
            //未支付
            let rentInfo = {};
            rentInfo.backTime = res.data.backResult.backTime;
            rentInfo.equId = equId;
            rentInfo.borrowTime = res.data.backResult.borrowTime;
            rentInfo.costTime = res.data.backResult.costTime;
            rentInfo.deposit = res.data.backResult.deposit;
            rentInfo.orderCode = res.data.backResult.orderCode;
            rentInfo.rent = res.data.backResult.rent;
            rentInfo.noPayTitle = res.data.backResult.noPayTitle;
            rentInfo.priceLabel = res.data.backResult.priceLabel;
            rentInfo.orderType = res.data.backResult.orderType;
            rentInfo.inCycleLeaseTimeLen = res.data.backResult.inCycleLeaseTimeLen || '';
            rentInfo.inCycleRecordInfoList = res.data.backResult.inCycleRecordInfoList || [];
            if (pt === 'no_back_tip') {
              wx.redirectTo({
                url: urlPre + '/no_pay_tip/no_pay_tip?rentInfo=' + JSON.stringify(rentInfo)
              })
            } else {
              wx.navigateTo({
                url: urlPre + '/no_pay_tip/no_pay_tip?rentInfo=' + JSON.stringify(rentInfo)
              })
            }
          } else {
            let urlPre = pt === 'no_back_tip' ? "../.." : "..";
            //归还成功
            if (pt === 'no_back_tip') {
              let pages = getCurrentPages()
              let currPage = pages[pages.length - 1]
              if (currPage.data.prevPageName == 'user_lease') {
                wx.showToast({
                  title: '归还成功！',
                })
                setTimeout(() => {
                  wx.reLaunch({
                    url: urlPre + '/index/index',
                  })
                }, 1500)
              } else {
                wx.redirectTo({
                  url: urlPre + '/user_record/lease/user_lease',
                })
              }
            } else {
              wx.navigateTo({
                url: urlPre + '/user_record/lease/user_lease',
              })
            }
          }

        } else {
          if (pt === 'no_back_tip' && _scanBoxFlg === true) {
            disconnect('BLE1086');
            _scanBoxFlg = false;
          } else {
            //连接已匹配的蓝牙设备
            setTimeout(function () {
              if (src && src == 'con2') {
                connection(_that);
              } else {
                createBLEConnection('BLE1100')
              }
            }, 10)
          }
        }
      },
      fail: function () {
        console.log("花费的时长f:" + (new Date().getTime() - curTime));
        if (pt === 'lease_tip') {
          return;
        }
        //连接已匹配的蓝牙设备
        setTimeout(function () {
          if (src && src == 'con2') {
            connection(_that);
          } else {
            createBLEConnection('BLE1116')
          }
        }, 10)
      },
      complete: function () {
        console.log("花费的时长:" + (new Date().getTime() - curTime));
      }
    })

  })

}

//连接已匹配的蓝牙设备
function createBLEConnection(lineNum) {


  if (_Device == null || _Device == '') {
    console.log("不存在连接的设备...")
    stopTimeout();
    return;
  }
  _currBlueConStage = 'createCon'

  console.log("【正在连接蓝牙设备中】" + _Device.name, _Device)

  a.globalData.isConnecting = true;
  a.globalData.conErrDesc = 'OLD:开始连接';
  wx.createBLEConnection({
    deviceId: _Device.deviceId,
    timeout: _CreateConnectionTimeoutSize,
    success: function (res) {
      // statusChanged(Status.bleConnectSuccess) 该状态没有使用
      console.log("【调用连接蓝牙设备函数完成】" + lineNum, res)
      a.globalData.isConnecting = false;
      //连接成功的类型
      a.globalData.connectSucType = 'ble'  
      commonUtil.recordErrorInfo(ConstantData.err_type.ble_create_con_suc, "创建连接成功b");
    },
    fail: function (res) {
      a.globalData.conErrDesc = 'OLD:连接失败:' + JSON.stringify(res);
      // statusChanged(Status.bleConnectFail) 该状态没有使用

      commonUtil.recordErrorInfo(ConstantData.err_type.ble_connect, "【wx.createBLEConnection】fail:" + JSON.stringify(res));
      console.error("【error】【wx.createBLEConnection】【调用连接蓝牙设备函数失败】" + lineNum, res)
      a.globalData.isConnecting = false;
      if (res.errCode == -1 && res.errMsg == 'createBLEConnection:fail:already connect') {
        return
      }
      //尝试重新连接
      retryConnect('BLE1151')
    }
  })

}

function guid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

//监听蓝牙设备连接状态变化
function onBLEConnectionStateChange() {
  _currBlueConStage = 'onBleConStatChange'

  console.log("【开始监听蓝牙设备连接状态变化】11")

  wx.onBLEConnectionStateChange(function (res) {
    if (_Device != null && res.deviceId == _Device.deviceId) {

      getApp().globalData.devConnected = res.connected;

      if (res.connected) {
        statusChanged(Status.bleReConnected)
        console.log("【蓝牙设备状态变化】【当前设备连接成功】", res)

        //延迟获取蓝牙设备的所有服务，查找满足要求的微信协议服务
        var delayTimeLen = _ServerConfigInfo.connectDelayed.getBLEDeviceServices
        if (_getBLEDeviceServiesRetryConCount == 1) {
          //第一次失败进行蓝牙重新连接后的延迟时间
          delayTimeLen = _getBLEDeviceServicesDelayTime
        }
        if (_getBLEDeviceServiesRetryConCount == 2) {
          //重连失败第二次重新连接,不进行函数调用直接使用uuid进行操作
          delayTimeLen = 500
        }
        setTimeout(function () {
          getBLEDeviceServices()
        }, delayTimeLen)

      } else {
        console.log("【蓝牙设备状态变化】【当前设备连接断开】", res)
        if (_IsFirstConnected == false) {
          //尝试重新连接
          retryConnect('BLE1193')
        } else {
          statusChanged(Status.bleDisconnected)

        }
      }
    } else {
      console.log("【蓝牙设备状态变化】【非当前设备】", res)
    }
  })

}

//获取蓝牙设备的所有服务，查找满足要求的微信协议服务
function getBLEDeviceServices() {
  _currBlueConStage = 'getServices'

  console.log("【正在获取、查找蓝牙设备的微信服务】")

  wx.getBLEDeviceServices({
    deviceId: _Device ? _Device.deviceId : '',
    success: function (res) {
      //函数调用成功重试连接计数归零
      _getBLEDeviceServiesRetryConCount = 0

      console.log("【当前蓝牙设备的服务列表】", res)

      var isFind = false
      for (var i = 0; i < res.services.length; i++) {
        if (res.services[i].uuid.indexOf("0000FEE7") == 0) {
          _WXServiceUUID = res.services[i].uuid
          isFind = true
          break
        }
      }

      if (isFind == false) {
        statusChanged(Status.bleNotSupportWXService)

        console.error("【error】【bleNotSupportWXService】【未匹配微信蓝牙协议服务】")

        return
      }

      statusChanged(Status.bleSupportWXService)

      console.log("【已匹配微信蓝牙协议服务】")

      //延迟获取服务的所有特征
      setTimeout(function () {
        getBLEDeviceCharacteristics()
      }, _ServerConfigInfo.connectDelayed.getBLEDeviceCharacteristics)

    },
    fail: function (res) {

      console.error("【error】【wx.getBLEDeviceServices】【获取、查找蓝牙设备的微信服务失败】", res)

      //记录失败的日志到服务器
      if (_getBLEDeviceServiesRetryConCount == 0) {

        console.log("【正常获取失败,重连蓝牙,wx.getBLEDeviceServices函数调用失败】")

      } else if (_getBLEDeviceServiesRetryConCount == 1) {

        console.log("【第一次重连蓝牙失败,再重连】")

      } else if (_getBLEDeviceServiesRetryConCount == 2) {
        //进行直连,走不到此判断
        console.log("【第二次重连失败，再连】")
      } else {
        console.log("【获取服务失败,再次重连】")
      }

      _getBLEDeviceServiesRetryConCount += 1
      //重新连接蓝牙获取服务列表
      retryConnect('BLE1276')

    }

  })

}

//获取服务的所有特征
function getBLEDeviceCharacteristics() {
  _currBlueConStage = 'getCharacter'

  console.log("【正在获取、查找蓝牙设备的微信特征】")

  let devId = _Device ? _Device.deviceId : '';

  wx.getBLEDeviceCharacteristics({
    deviceId: devId,
    serviceId: _WXServiceUUID,
    success: function (res) {

      console.log("【当前蓝牙设备的特征列表】", res)

      for (var i = 0; i < res.characteristics.length; i++) {
        if (res.characteristics[i].uuid.indexOf("FEC7") != -1) {
          _WXWriteUUID = res.characteristics[i].uuid
        } else if (res.characteristics[i].uuid.indexOf("FEC8") != -1) {
          _WXIndicateUUID = res.characteristics[i].uuid

          //启用特征值变化通知
          wx.notifyBLECharacteristicValueChange({
            state: true, // 启用 notify 功能
            deviceId: devId,
            serviceId: _WXServiceUUID,
            characteristicId: _WXIndicateUUID,
            success: function (res) {
              console.warn('开启了通知2');
            }
          })

        } else if (res.characteristics[i].uuid.indexOf("FEC9") != -1) {
          _WXReadUUID = res.characteristics[i].uuid
        }

      }

      if (_WXWriteUUID.length <= 0 || _WXIndicateUUID.length <= 0 || _WXReadUUID.length <= 0) {
        statusChanged(Status.bleNotSupportWXCharacteristic)
        console.error("【error】【bleNotSupportWXCharacteristic】【未匹配微信蓝牙协议特征】")

        return
      }

      _CollectionServiceInfo(_WXServiceUUID, _WXWriteUUID, _WXIndicateUUID, _WXReadUUID)

      console.log("【_WXWriteUUID】", _WXWriteUUID)
      console.log("【_WXReadUUID】", _WXReadUUID)
      console.log("【_WXIndicateUUID】", _WXIndicateUUID)

      statusChanged(Status.bleSupportWXCharacteristic)

      console.log("【已匹配微信蓝牙协议特征】")

      //监听微信蓝牙协议特征数据变化
      onBLECharacteristicValueChange()
    },
    fail: function (res) {
      console.error("【error】【wx.getBLEDeviceCharacteristics】【获取、查找蓝牙设备的微信特征失败】", res)
      console.log("【准备重新获取、查找蓝牙设备的微信特征】")

      //延迟获取服务的所有特征
      setTimeout(function () {
        getBLEDeviceCharacteristics()
      }, _ServerConfigInfo.connectDelayed.failGetBLEDeviceCharacteristics)

    }

  })

}

//监听微信蓝牙协议特征数据变化
function onBLECharacteristicValueChange() {
  _currBlueConStage = 'onBleCharacterChange'

  statusChanged(Status.bleReceiveData)
  console.log("【开始监听微信蓝牙协议特征数据变化】")

  wx.onBLECharacteristicValueChange(function (characteristic) {
    const hex = buf2hex(characteristic.value).toUpperCase()
    console.log("【=====================接收到设备发来的数据】", hex)
    handleDeviceData(hex)
  })

}


//校验接受到的数据crc16码是否正确
function validateCrc16Code(hexData) {
  let data = hexData.substring(0, hexData.length - 4);
  let vCode = hexData.substring(hexData.length - 4);
  console.log("crc16-->", data, vCode);
  let validateCode = CRC16.ToModbusCRC16(data);
  EncryptUtil.pad(validateCode, 4);
  if (validateCode != vCode) {
    console.log("【蓝牙连接】数据CRC16校验失败，无法处理", validateCode);
    return false;
  }
  return true;
}

//处理解析设备发来的数据
function handleDeviceData(hex, dev, receiveResData) {
  _currBlueConStage = 'handleDevData'
  a.globalData.conErrDesc = 'receivingData'
  console.log("【开始处理收到的蓝牙设备数据】", _Status)

  let that = getApp().globalData._that;
  if (that) {
    that.recordBlueConnectError(ConstantData.err_type.connect_receive_data, "收到的数据:" + hex);
  }

  if (_Status == Status.bleReceiveData || _Status == Status.ble01Data) { //接收数据状态，解析数据指令,这两种状态都需要数据解析

    var length;
    var version = '01';
    var seq;
    var command;
    if (a.globalData.conBlueVer && a.globalData.conBlueVer == 'om-phy-1.0') {
      //宜家陪护椅驱动
      var l = receiveResData.value,
        t = new Int8Array(l),
        r = aesDecrypt(t);
      parseValue(r);
      console.log("宜家陪护椅decryContent is" + r);
    } else if (hex.indexOf("E5") == 0) {
      let hexData = hex;
      let len = parseInt(hexData.substring(2, 4), 16) + 2;
      length = len.toString(16); //长度
      version = hexData.substring(4, 6); //版本
      seq = hexData.substring(6, 8); //seq
      command = hexData.substring(8, 10); //指令
    } else {
      version = hex.substring(2, 4) //版本号
      length = hex.substring(6, 8) //数据长度
      command = hex.substring(8, 12) //指令
      seq = hex.substring(12, 16) //seq
    }


    console.log("【version】" + version, parseInt(version, 16))
    console.log("【length】" + length, parseInt(length, 16))
    console.log("【command】" + command, parseInt(command, 16))
    console.log("【seq】" + seq, parseInt(seq, 16))


    if (command == '01' && length == '13') {

      console.info('【蓝牙连接】处理收到的随机数：', hex);
      let flg = validateCrc16Code(hex);
      if (!flg) {
        console.log("【蓝牙连接】随机数校验码失败");
        let that = getApp().globalData._that;
        if (that) {
          that.recordBlueConnectError(ConstantData.err_type.connect_random_err, "随机数校验码失败,数据:" + hex);
        }
        return;
      }
      _transferOpenLockCmd = true;
      _IsFirstConnected = true;
      //随机数
      _RandomNumKey = hex.substring(10, 18);
      console.info('【蓝牙连接】收到的随机数：', _RandomNumKey);
      //存储到全局变量中，用于当获取局部存储变量失败后使用，主要目的兼容之前代码
      getApp().globalData.boxRandomNumKey = _RandomNumKey;
      getApp().globalData._that.setData({
        randomNum: _RandomNumKey,
        blepwd: null
      })
      _Version = version;
      _driverVersion = hex.substring(28, 34);
      console.info('【蓝牙连接】硬件、软件版本号：' + _driverVersion);
      getApp().globalData.driveFirmwareVer = _driverVersion;

      var hardwareVersion = hex.substring(20, 22);
      console.info('【蓝牙连接】硬件号：' + hardwareVersion);
      getApp().globalData.hardwareVersion = hardwareVersion;

      var softwareVersion = hex.substring(18, 28);
      console.info('【蓝牙连接】软件版本：' + softwareVersion);
      getApp().globalData.softwareVersion = softwareVersion;

      let firmEquType = hex.substring(18, 20);
      console.info('【蓝牙连接】设备类型：' + firmEquType);
      getApp().globalData.firmEquType = firmEquType;

      statusChanged(Status.ble01Data);

      clearTimeout(getApp().globalData.auto95RecTimer);

      //增加接收自动上报95数据的超时限制
      getApp().globalData.auto95RecTimer = setTimeout(function () {
        send95Command(function (isSuc) {
          if (getApp().globalData._that) {
            if (isSuc == false) {
              getApp().globalData._that.handleStatus(Status.bleSend95Timeout);
            } else {
              getApp().globalData._that.handleStatus(Status.bleReciveAuto95Timeout);
            }
          } else {
            wx.showModal({
              title: '温馨提示',
              content: '蓝牙数据未获取，请重新扫码',
            })
          }
        });
      }, 8000);

    } else if (_RandomNumKey.length > 0) {
      statusChanged(Status.bleReceiveBaseData)
      console.log("【接收普通数据】正在接收普通数据...")

      _DataString = null
      _DataString = hex
      _DataSize = parseInt(length, 16)


      //检查是否已接收完普通数据
      checkReceiveData()

    } else if (parseInt(command, 16) == 10001) {
      statusChanged(Status.bleReceiveAuthData)
      console.log("【请求Auth指令】正在接收Auth数据...")


      _AuthString = null
      _AuthString = hex
      _AuthSize = parseInt(length, 16)

    } else if (parseInt(command, 16) == 10003) {
      statusChanged(Status.bleReceiveInitData)
      console.log("【请求Init指令】正在接收Init数据...")

      _InitString = null
      _InitString = hex
      _InitSize = parseInt(length, 16)

      //检查是否已接收完初始化数据
      checkReceiveInit()

    } else if (parseInt(command, 16) == 10002) {
      statusChanged(Status.bleReceiveBaseData)
      console.log("【接收普通数据】正在接收普通数据1...")

      _DataString = null
      _DataString = hex
      _DataSize = parseInt(length, 16)

      //检查是否已接收完普通数据
      checkReceiveData()

    }

  } else if (_Status == Status.bleReceiveAuthData) { //接收剩余授权数据
    _AuthString = _AuthString + hex

  } else if (_Status == Status.bleReceiveInitData) { //接收剩余初始化数据
    _InitString = _InitString + hex

    //检查是否已接收完初始化数据
    checkReceiveInit()
  } else if (_Status == Status.bleReceiveBaseData) { //接收剩余普通数据
    _DataString = _DataString + hex

    //检查是否已接收完普通数据
    checkReceiveData()
  }

}


//检查是否已接收完初始化数据
function checkReceiveInit() {
  if (_InitString.length >= _InitSize * 2) {

    var initRequest = EncryptUtil.parseInitRequest(_InitString, _InitSize, _EncryptValue, _TimeBytes)

    // _InitString = _InitString.substring(0, _InitSize * 2)
    statusChanged(Status.bleReceiveData)
    // console.log("【请求Init指令】接收Init数据完成...")
    // console.log("【请求Init指令】完整Init数据：", _InitString)

    //校验初始化数据，并发送初始化请求响应数据包
    checkInitAndSendInitResponse(initRequest)

    return
  }
}

//检查是否已接收完普通数据
function checkReceiveData() {
  let app = getApp();
  let that = app.globalData._that;
  let totalLen = _DataSize * 2;
  let isOverFlg = _DataString.length >= totalLen;
  let isOld = isOldProcy();

  if (that) {
    that.recordBlueConnectError(ConstantData.err_type.ble_msg_receive_flg, "数据包长度:" + _DataString.length + "," + _DataSize + ";isOver:" + isOverFlg + ";isOld:" + isOld);
  }

  if (isOverFlg) {
    let receiveData = _DataString;
    if (isOld) {
      return parseData(isOld, receiveData);
    }

    //校验CRC16
    let flg = validateCrc16Code(receiveData);
    if (!isOld && !flg) {
      console.log("【蓝牙连接】数据CRC16校验失败，无法处理");
      if (that) {
        that.recordBlueConnectError(ConstantData.err_type.connect_data_err, "数据CRC16校验失败:" + _DataString);
        if (_RandomNumKey) {
          //重新发送95数据
          send95Command(function (isSuc) {
            if (isSuc == false) {
              that.handleStatus(BLELocker.Status.bleSend95Timeout);
            } else {
              that.handleStatus(BLELocker.Status.bleRecive95Timeout);
            }
          });
        } else {
          that.setData({
            loading_show: false,
            alertBoxStatus: true,
            alertBoxTipContent: "重新扫码重试",
            alertBoxBtnName: "确 定"
          })
        }
      }

      return;
    }


    let app = getApp();
    let that = app.globalData._that;
    clearTimeout(app.globalData.auto95RecTimer);
    if (that.data.blepwd) {
      return parseData(isOld, receiveData);
    }
    let randomKey = that && that.data.randomNum ? that.data.randomNum : _RandomNumKey;
    let pwdMac = that && that.data.mac ? that.data.mac : getApp().globalData.mac;
    let startTime = new Date().getTime();
    //重新获取秘钥
    app.executeRequest(function (header) {
      wx.request({
        url: ConstantData.CONSTATNT_DATA.BASE_URL + '/ble/pwd',
        method: 'post',
        header: header,
        data: {
          mac: pwdMac,
          random: randomKey
        },
        success: function (res) {
          console.log("pwd:", res);
          let timeLen = new Date().getTime() - startTime;
          if (timeLen > 5000) {
            let resStr = res ? JSON.stringify(res) : '';
            that.recordBlueConnectError(ConstantData.err_type.data_key_err, "秘钥时长过长:" + timeLen + ";res=" + resStr);
          }
          if (res.data.result == 0) {
            let pwd = res.data.data;
            that.data.blepwd = pwd;
            return parseData(isOld, receiveData);
          } else {
            getApp().hideLoading()

            //1.关闭正在连接的提示对话框 2.弹出提示用户APP版本太低不支持的对话框
            that.setData({
              loading_show: false,
              alertBoxStatus: true,
              alertBoxTipContent: "连接秘钥错误",
              alertBoxBtnName: "确 定"
            })
            let _that = _that ? _that : getApp().globalData._that;
            if (_that && typeof (_that.recordBlueConnectError) === "function") {
              that.recordBlueConnectError(ConstantData.err_type.data_key_err, "秘钥错误:" + that.data.curBlueName);
            }

          }
        }
      })
    });


    return
  }
}

function parseData(isOld, recData) {
  let bussinessData = EncryptUtil.getBussinessData(recData, _DataSize, _transferOpenLockCmd, isOld)

  if (_BaseDataCallBack != null) {
    _BaseDataCallBack(bussinessData)
    statusChanged(Status.bleReceiveData)
    _BaseDataCallBack = null
    return
  }


  // console.log("【接收普通数据】接收普通数据完成...")
  console.log("【接收普通数据】完整普通数据：", recData)
  console.log("【接收普通数据】解密后的数据：", bussinessData)
  let _that = _that ? _that : getApp().globalData._that;
  if (!bussinessData && _that && typeof (_that.recordBlueConnectError) === "function") {
    _that.recordBlueConnectError(40020, 'bussinessData空：_DataString=' + recData + ' curDevName=' + _that.data.curDevName);
    _that.recordBlueConnectError(40020, '_Data95=' + (_Data95 ? JSON.stringify(_Data95) : 'null'));
  }
  if (bussinessData && bussinessData.cmdId == "88") { //85指令响应数据


    _Data85 = bussinessData.data
    _Data88 = bussinessData.data

    console.log("【接收普通数据】88指令响应数据", _Data88)

    statusChanged(Status.ble88Data)

  } else if (bussinessData && bussinessData.cmdId == "85") { //85指令响应数据

    _Data85 = bussinessData.data

    console.log("【接收普通数据】85指令响应数据", _Data85)

    statusChanged(Status.ble85Data)

  } else if (bussinessData && bussinessData.cmdId == "13") { //1301指令响应数据

    _Data1301 = bussinessData.data

    console.log("【接收普通数据】1301指令响应数据", _Data1301)

    statusChanged(Status.ble1301Data)

  } else if (bussinessData && bussinessData.cmdId == "95") { //95指令响应数据

    _Data95 = bussinessData.data
    if (_driverVersion == null && _Data95.pile_ver) {
      //兼容新固件新驱动
      _driverVersion = _Data95.pile_ver;
    } else if (_driverVersion && _Data95 && !_Data95.pile_ver) {
      _Data95.pile_ver = _driverVersion;
    }
    _Data95.hardwareVersion = getApp().globalData.hardwareVersion
    _Data95.softwareVersion = getApp().globalData.softwareVersion
    console.log("【接收普通数据】95指令响应数据", _Data95)

    if (_IsFirstConnected) {
      getApp().lajax.setConRFID(_Data95.rfid)
      console.log("【连接共享轮椅---终点】", _reqId, _DeviceName);
      getApp().lajax.sendLog();
    }
    statusChanged(Status.ble95Data)

  } else if (bussinessData && bussinessData.cmdId == "98") { //98指令响应数据

    _Data98 = bussinessData.data

    console.log("【接收普通数据】98指令响应数据", _Data98)

    statusChanged(Status.ble98Data)

  } else if (bussinessData && bussinessData.cmdId == "75") { //75指令响应数据

    if (getApp().globalData.auto95RecTimer) {
      //取消掉默认接收95超时的重试
      clearTimeout(getApp().globalData.auto95RecTimer);
      getApp().globalData.auto95RecTimer = null;
    }

    let seqNum = bussinessData.data.seqNum
    console.log("【接收普通数据】75指令响应数据", seqNum, bussinessData.data)
    if (seqNum == '00') {
      //第0包数据
      _Data75Zero = bussinessData.data;
      statusChanged(Status.ble75zeroData);
    } else {
      //各个门的状态信息
      _Data75N = bussinessData.data;
      statusChanged(Status.ble75NData);
    }

  } else if (bussinessData && bussinessData.cmdId == "76") { //76指令响应数据
    _Data76 = bussinessData.data
    statusChanged(Status.ble76Data)
  } else {
    let busiData = bussinessData ? bussinessData.data : null;
    commonUtil.recordErrorInfo(ConstantData.err_type.connect_cmd_err, '命令不存在:' + busiData)
    console.log("【蓝牙连接】未处理的响应数据", busiData);
  }
  statusChanged(Status.bleReceiveData)
}

//校验初始化数据，并发送初始化请求响应数据包
function checkInitAndSendInitResponse(initRequest) {
  _currBlueConStage = 'checkInit'

  //校验初始化数据正确性，这里目前未校验，默认认为是合法的设备
  // var hex = "FE0100194E2300020A02080010B42418F8AC0120D1BBCABF07"

  let initResponseData = EncryptUtil.getInitResponseData(_EncryptValue, _TimeBytes, initRequest, 4660, 22136, 0, '')

  console.log("【响应Init指令】开始发送数据...", initResponseData)

  if (_Device != null) {
    writeData(initResponseData, function (isSuccess) {
      if (isSuccess) {
        console.log("【响应Init指令】发送数据成功...")

        statusChanged(Status.bleInitSuccess)
        statusChanged(Status.bleReceiveData)
        console.log("【===设备授权初始化完成===】")

        _IsFirstConnected = true

        //发送95指令给设备
        send95Command(null)

      } else {
        console.error("【error】【send init data fail】【响应Init指令】发送数据失败...")

        //发送失败，重新校验初始化数据，并发送初始化请求响应数据包
        checkInitAndSendInitResponse(initRequest)
      }
    }, 40)
  }

}

//发送控制盒广播配置信息
function sendBroadcastConfCommand() {
  let flg = isOldProcy();
  if (!flg) {
    return;
  }
  var _that = getApp().globalData._that;
  var params = _that && _that.data.conDevExtParams ? _that.data.conDevExtParams.broadcast88conf : "";
  if (params) {
    var hexStr = 'FE01001400510000' + params + "00";
    var crc16 = CRC16.ToModbusCRC16(hexStr);;
    var hex = hexStr + crc16;
    console.log("---sendBroadcastConCommand-->", hex);
    writeData(hex, function (isSuccess) {
      console.log("---sendBroadcastConCommand--isSuc=", isSuccess);
    });
  }


}

//发送85指令给设备
function send85Command(callback) {
  getApp().globalData.gatewayUnlockFlg = false
  _BaseDataCallBack = null
  _currBlueConStage = 'send85'
  console.log('send85Command', _Status)
  stopSendCommandTimeout();
  start85Back1Timeout(Status.ble85Back1Timeout);

  _Data85 = null //解析后的85数据
  // var hex = 'FE010010753100000A00120238351800'

  let sendHexStr;

  if (_transferOpenLockCmd) {
    sendHexStr = EncryptUtil.getSendDataRequestHexStr('88', isOldProcy(), _Version);
    console.log('【蓝牙连接】准备发送88指令数据：' + sendHexStr);
  } else {
    sendHexStr = EncryptUtil.getSendDataRequestHexStr('85', isOldProcy(), _Version);
    console.log('【蓝牙连接】准备发送85指令数据：' + sendHexStr);
  }

  if (!_Device) {
    _Device = getApp().globalData.conDevice;
  }

  if (_Device != null) {
    console.log("【发送88指令】开始发送数据...", sendHexStr)
    a.globalData.RSSI = _Device.RSSI;
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        if (_driverVersion && _driverVersion.slice(-6) >= '191101') { //新新驱动
          start85Back2Timeout(Status.ble85Back2Timeout);
        }
        console.log("【发送88指令】发送数据成功...");
      }
      if (callback != null) {
        callback(isSuccess)
      }

    }, 40)
  } else {
    commonUtil.recordErrorInfo(ConstantData.err_type.data_85_send_no_dev, '发送开锁指令时 _Device is null')
    if (callback != null) {
      callback(false);
    }
  }
}

//发送1301指令给设备
function send1301Command(callback) {
  _BaseDataCallBack = null
  _currBlueConStage = 'send1301'
  console.log('send1301Command', _Status)
  stopSendCommandTimeout();

  _Data1301 = null //解析后的1301数据
  // var hex = 'FE010010753100000A00120238351800'

  let sendHexStr;

  sendHexStr = EncryptUtil.getSendDataRequestHexStr('1301', isOldProcy(), _Version);
  console.log('【蓝牙连接】准备发送13指令数据：' + sendHexStr);
  console.log("【发送13指令】开始发送数据...", sendHexStr)

  if (!_Device) {
    _Device = getApp().globalData.conDevice;
  }
  if (_Device != null) {
    console.log(_Device, '_Device_RSSIA')
    a.globalData.RSSI = _Device.RSSI;
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        if (_driverVersion && _driverVersion.slice(-6) >= '191101') { //新新驱动
        }
        console.log("【发送13指令】发送数据成功...")
        getApp().hideLoading();

        // if (callback != null) {
        //   callback(true)
        // }
      } else {
        console.error("【error】【send 85 data fail】【发送85指令】发送数据失败...")
        if (callback == null) {
          //发送失败，重新发送85指令
          send1301Command(callback)
        } else {
          // callback(false)
        }
      }
    }, 40)
  }
}
//心跳包
function send90Command(step) {
  if (!step) {
    step = '0';
  } else if (parseInt(step, 16) < 11) {
    step = '0' + step;
  }
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('90' + step, isOldProcy())
  console.log("【发送90指令】开始发送数据...", sendHexStr)
  if (!_Device) {
    _Device = getApp().globalData.conDevice;
  }
  if (_Device != null) {
    console.log(_Device, '_Device_RSSIB')
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送90指令】发送数据成功...")
      } else {
        console.error("【error】【send 90 data fail】【发送90指令】发送数据失败...")
      }
    }, 40)
  }
}

//发送95指令给设备
function send95Command(callback) {
  _BaseDataCallBack = null
  _currBlueConStage = 'send95'
  if (!getApp().globalData.devConnected) {
    getApp().globalData._that.handleStatus(Status.bleSend95ConDis);
    return;
  }
  getApp().globalData.startConTime = new Date().getTime();
  commonUtil.recordErrorInfo(ConstantData.err_type.data_95_send, '发送95指令')

  _Data95 = null //解析后的95数据
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('95', isOldProcy(), _Version)
  console.log("【发送95指令】开始发送数据...", sendHexStr)

  if (!_Device) {
    _Device = getApp().globalData.conDevice;
  }
  if (_Device != null) {
    startSendCommandTimeout(Status.bleSend95Timeout)
    let send95StartTime = getApp().globalData.startSend95Time;
    let startTime = new Date().getTime();
    let diff = !send95StartTime ? 8000 : startTime - send95StartTime;
    let delayMills = 500;
    if (diff <= 5000) {
      //延迟8秒后就延迟发送95指令,连续发送95指令驱动会舍弃不处理
      let leftDelay = 8000 - diff;
      delayMills = leftDelay <= 0 ? 8000 : leftDelay;
    }

    setTimeout(function () {
      writeData(sendHexStr, function (isSuccess) {
        if (isSuccess) {
          getApp().globalData.startSend95Time = new Date().getTime();
          console.log("【发送95指令】发送数据成功...")
          commonUtil.recordErrorInfo(ConstantData.err_type.data_95_send, '发送95指令:suc')
          getApp().globalData.data95ReceiveTimer = setTimeout(function () {
            console.log("95数据接收超时...", callback);
            if (getApp().globalData._that) {
              getApp().globalData._that.handleStatus(Status.bleRecive95Timeout);
            }
          }, 15000);
          if (callback != null) {
            callback(true)
          }

        } else {
          console.error("【error】【send 95 data fail】【发送95指令】发送数据失败...")

          if (callback == null) {
            //发送失败，重新发送95指令
            send95Command(callback)
          } else {
            callback(false)
          }

        }
      }, 40)
    }, delayMills);
  } else {
    getApp().globalData._that.handleStatus(Status.bleSend95DevNull);
  }

}

//发送95指令给设备
function send98Command(callback) {
  _BaseDataCallBack = null
  _currBlueConStage = 'send98'

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  _Data98 = null //解析后的95数据
  // var hex = 'FE010010753100000A00120239351800'
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('98', isOldProcy(), _Version)

  console.log("【发送98指令】开始发送数据...", sendHexStr)

  if (!_Device) {
    _Device = getApp().globalData.conDevice;
  }
  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送98指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }

      } else {
        console.error("【error】【send 98 data fail】【发送98指令】发送数据失败...")

        if (callback == null) {
          //发送失败，重新发送95指令
          send98Command(callback)
        } else {
          callback(false)
        }

      }
    }, 40)
  }

}

//发送75指令获取设备状态
function send75Command(callback, params) {
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('75' + params, isOldProcy(), _Version)
  console.log("【发送75指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    console.log(_Device, '_Device_RSSIC')
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送75指令】发送数据成功...")
        if (params == '00') {
          //第0包发送命令超时限制
          getApp().globalData.data75ReceiveTimer = setTimeout(function () {
            console.log("75数据接收超时...", callback);
            if (getApp().globalData._that) {
              getApp().globalData._that.handleStatus(Status.bleRecive75Timeout);
            }
          }, 8000);
        }

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【send 75 data fail】【发送75指令】发送数据失败...")
        if (callback == null) {} else {
          callback(false)
        }
      }
    }, 40)
  }
}

//发送76指令获取设备状态
function send76Command(callback, params) {
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('76' + params, isOldProcy(), _Version)
  console.log("【发送76指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    console.log(_Device, '_Device_RSSIC')
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送76指令】发送数据成功...")

        //第0包发送命令超时限制
        getApp().globalData.data76ReceiveTimer = setTimeout(function () {
          console.log("76数据接收超时...", callback);
          if (getApp().globalData._that) {
            getApp().globalData._that.handleStatus(Status.bleRecive76Timeout);
          }
        }, 8000);

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【send 75 data fail】【发送75指令】发送数据失败...")
        if (callback == null) {} else {
          callback(false)
        }
      }
    }, 40)
  }
}

function sendPeiHuYiBleGetToken(callback) {
  let app = getApp();
  let sendCmd = app.globalData.bleVariable.cmds.getTokenCmd;
  console.log("【发送陪护椅token指令】开始发送数据...", sendCmd)

  if (_Device != null) {
    console.log(_Device, '_Device_RSSIC')
    writePeiHuYiCommDevice(sendCmd, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送陪护椅token指令】发送数据成功...")

        //陪护椅token指令超时限制
        getApp().globalData.dataPeiHuYiTokenReceiveTimer = setTimeout(function () {
          console.log("陪护椅token指令...", callback);
          if (getApp().globalData._that) {
            getApp().globalData._that.handleStatus(Status.bleReciveOneMorePhyTokenTimeout);
          }
        }, 8000);

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【发送陪护椅token指令】发送数据失败...")
        if (callback == null) {} else {
          callback(false)
        }
      }
    })
  }
}
//宜家陪护椅开锁发送命令
function oneMorePhyBleUnlock() {
  var e = getApp();
  console.log("0000000000000000unlock"), e.globalData.isUnlocked = !1;
  for (var a = 0; a < e.globalData.bleVariable.cmds.unlockCmd.length; a++) a <= 2 || (a >= 3 && a <= 8 ? e.globalData.deviceKind == e.globalData.deviceKindBed ? e.globalData.bleVariable.cmds.unlockCmd[a] = e.globalData.bleVariable.unlockPwd[a - 3] : e.globalData.bleVariable.cmds.unlockCmd[a] = e.globalData.bleVariable.drawerUnlockPwd[a - 3] : e.globalData.bleVariable.cmds.unlockCmd[a] = a >= 9 && a <= 12 ? e.globalData.bleVariable.token[a - 9] : Math.round(100 * Math.random()));
  console.log("that.globalData.bleVariable.cmds.unlockCmd is " + e.globalData.bleVariable.cmds.unlockCmd);

  startSendCommandTimeout(Status.bleSendOneMorePhyUnlockTimeout)
  let cmdUnlock = e.globalData.bleVariable.cmds.unlockCmd
  console.log("宜家陪护椅开始开锁", cmdUnlock);
  writePeiHuYiCommDevice(cmdUnlock, function (isSuccess) {
    console.log("宜家陪护椅开锁命令是否发送成功:" + isSuccess);
    if (isSuccess) {
      stopSendCommandTimeout();
    }
  });
}
//宜家陪护椅锁住命令
function oneMorePhyBleLock() {
  var e = getApp();
  console.log("lock");
  for (var a = 0; a < e.globalData.bleVariable.cmds.lockCmd.length; a++) a <= 3 || (e.globalData.bleVariable.cmds.lockCmd[a] = a >= 4 && a <= 7 ? e.globalData.bleVariable.token[a - 4] : Math.round(100 * Math.random()));
  console.log("that.globalData.bleVariable.cmds.lockCmd is " + e.globalData.bleVariable.cmds.lockCmd),
    writePeiHuYiCommDevice(e.globalData.bleVariable.cmds.lockCmd, function (isSuccess) {
      console.log("宜家陪护椅上锁命令是否发送成功:" + isSuccess);
    });
}

//陪护椅发送命令方式
function writePeiHuYiCommDevice(cmd, callback) {
  console.log("commDevice,cmd is " + cmd, _Device);
  let l = new Int8Array(cmd);
  console.log("Before Encrypt binary array is" + l);
  var t = aesEncrypt(l);
  console.log("Encrypt binary array is" + t);
  wx.writeBLECharacteristicValue({
    deviceId: _Device.deviceId,
    serviceId: _WXServiceUUID,
    characteristicId: _WXWriteUUID,
    value: t.buffer,
    success: function (res) {
      console.log("【wx.writeBLECharacteristicValue】【发送数据成功】", cmd);
      //发送指令成功后关闭超时机制
      stopSendCommandTimeout();
      if (callback) {
        callback(true)
      }
    },
    fail: function (res) {
      console.error("【error】【wx.writeBLECharacteristicValue】【发送数据失败】", res)
      if (callback) {
        callback(false)
      }
      let _that = _that ? _that : getApp().globalData._that;
      if (_that && typeof (_that.recordBlueConnectError) === "function") {
        _that.recordBlueConnectError(40020, 'write failA:' + JSON.stringify(res));
      }
    }
  })
}

function aesEncrypt(e) {
  var a = getApp(),
    o = e;
  console.log("Encrypt acontent is " + o);
  var l = aesUtil.CryptoJS.enc.int8array.parse(o),
    t = (l.toString(aesUtil.CryptoJS.enc.Base64),
      aesUtil.CryptoJS.AES.encrypt(l, a.globalData.bleVariable.keyWA, {
        iv: a.globalData.bleVariable.ivWA,
        mode: aesUtil.CryptoJS.mode.ECB,
        padding: aesUtil.CryptoJS.pad.NoPadding
      }));
  return aesUtil.CryptoJS.enc.int8array.stringify(t.ciphertext);
}

function aesDecrypt(e) {
  var a = getApp(),
    o = e,
    l = aesUtil.CryptoJS.enc.int8array.parse(o).toString(aesUtil.CryptoJS.enc.Base64),
    t = aesUtil.CryptoJS.AES.decrypt(l, a.globalData.bleVariable.keyWA, {
      iv: a.globalData.bleVariable.ivWA,
      mode: aesUtil.CryptoJS.mode.ECB,
      padding: aesUtil.CryptoJS.pad.NoPadding
    });
  return console.log("Decrypt decrypted is " + t), aesUtil.CryptoJS.enc.int8array.stringify(t);
}
//解析宜家陪护椅驱动数据
function parseValue(e) {
  var a = getApp();
  console.log("value is" + e), console.log("value.toString().indexOf(getTokenPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.getTokenPrefix)),
    console.log("value.toString().indexOf(queryLockStatusPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.queryLockStatusPrefix)),
    console.log("value.toString().indexOf(queryLockBatteryPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.queryLockBatteryPrefix)),
    console.log("value.toString().indexOf(unlockPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.unlockPrefix)),
    console.log("value.toString().indexOf(lockPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.lockPrefix)),
    console.log("value.toString().indexOf(deviceDisconnectPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.deviceDisconnectPrefix)),
    console.log("value.toString().indexOf(unknowCmdPrefix) is" + e.toString().indexOf(a.globalData.bleVariable.dataPrefix.unknowCmdPrefix)),
    0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.getTokenPrefix) ? parseGetToken(e) :
    0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.queryLockStatusPrefix) ? parseQueryLockStatus(e) :
    0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.queryLockBatteryPrefix) ? parseQueryLockBattery(e) :
    0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.unlockPrefix) ? parseUnlock(e) :
    0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.lockPrefix) || 0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.lockPrefix2) ? parseLock(e) :
    0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.deviceDisconnectPrefix) ? parseDeviceDisconnect(e) : 0 == e.toString().indexOf(a.globalData.bleVariable.dataPrefix.unknowCmdPrefix) ? parseUnknownCmd(e) : startBleCommErrCallback("命令异常");
}
//解析获取到的令牌信息
function parseGetToken(e) {
  if (getApp().globalData.dataPeiHuYiTokenReceiveTimer) {
    clearTimeout(getApp().globalData.dataPeiHuYiTokenReceiveTimer);
  }

  for (var a = getApp(), o = 3; o < 7; o++) a.globalData.bleVariable.token[o - 3] = e[o];
  console.log("token is " + a.globalData.bleVariable.token), setTimeout(function () {
    // queryLockStatus();
    queryBattery();
  }, 200);
}
//查询宜家陪护椅锁的状态
function queryLockStatus() {
  console.log("queryLockStatus");
  for (var e = getApp(), a = 0; a < e.globalData.bleVariable.cmds.queryLockStatusCmd.length; a++) a <= 3 || (e.globalData.bleVariable.cmds.queryLockStatusCmd[a] = a >= 4 && a <= 7 ? e.globalData.bleVariable.token[a - 4] : Math.round(100 * Math.random()));
  e = getApp();
  console.log("that.globalData.bleVariable.cmds.queryLockStatusCmd is " + e.globalData.bleVariable.cmds.queryLockStatusCmd),
    writePeiHuYiCommDevice(e.globalData.bleVariable.cmds.queryLockStatusCmd, function (isSuccess) {
      console.log("获取锁状态命令发送结果：" + isSuccess);
    });
}
//查询one more陪护椅的电量
function queryBattery() {
  console.log("queryBattery");
  for (var e = getApp(), a = 0; a < e.globalData.bleVariable.cmds.queryBatteryCmd.length; a++) a <= 3 || (e.globalData.bleVariable.cmds.queryBatteryCmd[a] = a >= 4 && a <= 7 ? e.globalData.bleVariable.token[a - 4] : Math.round(100 * Math.random()));
  e = getApp();
  console.log("that.globalData.bleVariable.cmds.queryBatteryCmd is " + e.globalData.bleVariable.cmds.queryBatteryCmd),
    writePeiHuYiCommDevice(e.globalData.bleVariable.cmds.queryBatteryCmd, function (isSuccess) {
      console.log("获取锁电量发送命令结果：" + isSuccess);
      if (!isSuccess) {
        //获取电量失败后，直接请求锁状态信息
        queryLockStatus();
      }
    });
}
//解析宜家陪护椅锁状态
function parseQueryLockStatus(e) {
  var a = getApp();
  console.log("parseQueryLockStatus", e);
  var halStatus = e[3],
    localLockStatus = e[4];
  console.log("parseQueryLockStatus halStatus is" + halStatus + " localLockStatus = " + localLockStatus);

  getApp().hideLoading()

  _DataOneMorePhyLockStatusData = new Object();
  _DataOneMorePhyLockStatusData.command = 'OM050E'; //指令 查询锁状态
  _DataOneMorePhyLockStatusData.rfid = '00000000'; //RFID
  _DataOneMorePhyLockStatusData.mac = a.globalData.curConMac; //设备MAC地址
  _DataOneMorePhyLockStatusData.costTime = '0'; //时间
  _DataOneMorePhyLockStatusData.electrict = _DataOneMorePhyLockBattery ? _DataOneMorePhyLockBattery.electrict : -1; //剩余电量
  //1表示锁舌弹出，对应锁钩开关应该为0
  let lockStatus = parseInt(localLockStatus, 16);
  _DataOneMorePhyLockStatusData.hookStatus = lockStatus == 1 ? 0 : 1; // 1不对 0对
  _DataOneMorePhyLockStatusData.powerOnCount = -1;
  //磁开关0表示未锁住，1表示锁住，对应插入开关
  _DataOneMorePhyLockStatusData.chairSwitchSatus = parseInt(halStatus, 16); //0未锁住 1已锁住
  _DataOneMorePhyLockStatusData.programRestartTimes = -1; //滴滴两声 0非滴滴，1滴滴两声
  _DataOneMorePhyLockStatusData.programRestartErrCode = -1; //自动修复次数
  _DataOneMorePhyLockStatusData.rfidIsCache = -1;
  _DataOneMorePhyLockStatusData.rfidRepeatCount = -1;
  _DataOneMorePhyLockStatusData.rfidReadErrCode = '';
  _DataOneMorePhyLockStatusData.motorStat = '';
  _DataOneMorePhyLockStatusData.loseChair = '';
  _DataOneMorePhyLockStatusData.unlockErrCode = '';

  _DataOneMorePhyLockStatusData.chairIsEjectLose = 0;
  _DataOneMorePhyLockStatusData.box_time = '';
  _DataOneMorePhyLockStatusData.recent_electrict = -1;
  _DataOneMorePhyLockStatusData.extVal = '';

  statusChanged(Status.bleOneMorePhyLockStatusData)

}
//解析one more 陪护椅的锁电量信息
function parseQueryLockBattery(e) {
  console.log("parseQueryLockBattery");
  var a = e[3];
  _DataOneMorePhyLockBattery = new Object();
  _DataOneMorePhyLockBattery.mac = getApp().globalData.curConMac; //设备MAC地址
  _DataOneMorePhyLockBattery.electrict = e[3];
  // statusChanged(Status.bleOneMorePhyLockBattery)
  //获取完电量后获取锁状态
  queryLockStatus();

  console.log("lockBattery is" + a);
}

//解析one more陪护椅开锁命令返回值
function parseUnlock(e) {
  console.log("parseUnlock");
  _DataOneMorePhyUnLockData = new Object();
  _DataOneMorePhyUnLockData.mac = getApp().globalData.curConMac;
  _DataOneMorePhyUnLockData.noEject = e[3];
  statusChanged(Status.bleOneMorePhyUnLockData)

  setTimeout(function () {
    disconnect("linenum2563");
    getApp().hideLoading();
  }, 1e4);
}
//解析one more 陪护椅归还锁住命令返回值
function parseLock(e) {
  console.log("parseLock");
  if (0 == e[3]) {
    console.log("one more 陪护椅锁成功");
  } else {
    console.log("one more 陪护椅锁失败");
  }
}
//解析one more陪护椅未知命令
function parseUnknownCmd(e) {
  console.log("unknowCmdPrefix");
}
//解析one more陪护椅异常命令
function startBleCommErrCallback(err) {
  console.log("命令异常错误:", err);
}
//解析one more陪护椅断开连接
function parseDeviceDisconnect(err) {
  console.log("断开连接:", err);
}

//发送B0指令给设备
function sendB0Command(callback) {
  _BaseDataCallBack = null
  _currBlueConStage = 'sendB0'

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  if (callback != null) {
    startSendCommandTimeout(Status.bleSendB0Timeout)
  }

  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('B0', isOldProcy())

  console.log('【蓝牙连接】准备发送B0指令数据：' + sendHexStr);
  console.log("【发送B0指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      stopSendCommandTimeout()
      if (isSuccess) {
        console.log("【发送B0指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【send B0 data fail】【发送B0指令】发送数据失败...")
        if (callback == null) {
          //发送失败，重新发送B0指令
          sendB0Command(callback)
        } else {
          callback(false)
        }
      }
    }, 40)
  }
}

//发送BASE指令
function sendBaseCommand(command, callback, dataCallback) {
  _BaseDataCallBack = null
  _currBlueConStage = 'sendBase'

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  _BaseDataCallBack = dataCallback

  if (callback != null) {
    startSendCommandTimeout(Status.bleSendBaseTimeout)
  }

  console.log('【蓝牙连接】准备发送BASE指令：' + command);
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr(command, isOldProcy())
  console.log('【蓝牙连接】准备发送BASE指令数据：' + sendHexStr);
  console.log("【发送BASE指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      stopSendCommandTimeout()
      if (isSuccess) {
        console.log("【发送BASE指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【send BASE data fail】【发送BASE指令】发送数据失败...")
        if (callback == null) {
          //发送失败，重新发送BASE指令
          sendBaseCommand(command, callback, dataCallback)
        } else {
          callback(false)
        }
      }
    }, 40)
  }
}

//发送数据给设备
function writeData(hex, callback, cmdSize) {
  //每次发送都延迟一下
  setTimeout(function () {

    if (_Device == null) {
      commonUtil.recordErrorInfo(ConstantData.err_type.data_send_cmd_no_dev, '发送指令时 _Device is null;' + hex)
      if (callback != null) {
        callback(false);
      }
      return
    }

    var sendHex = hex
    var lastHex = null

    //发送的数据长度大于40，拆分后发送
    if (hex.length > cmdSize) {
      sendHex = hex.substring(0, cmdSize)
      lastHex = hex.substring(cmdSize, hex.length)
    } else {
      lastHex = null
    }

    var typedArray = new Uint8Array(sendHex.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    var buffer = typedArray.buffer
    console.log("【正在发送数据】", sendHex, typedArray, _Device, _WXServiceUUID, _WXWriteUUID)

    wx.writeBLECharacteristicValue({
      deviceId: _Device.deviceId,
      serviceId: _WXServiceUUID,
      characteristicId: _WXWriteUUID,
      value: buffer,
      success: function (res) {
        console.log("【wx.writeBLECharacteristicValue】【发送数据成功】", lastHex);
        //发送指令成功后关闭超时机制
        stopSendCommandTimeout();
        if (lastHex == null) {
          callback(true)
        } else {
          writeData(lastHex, callback, cmdSize)
        }
      },
      fail: function (res) {
        console.error("【error】【wx.writeBLECharacteristicValue】【发送数据失败】", res)
        callback(false)
        commonUtil.recordErrorInfo(ConstantData.err_type.data_send_cmd_fail, '发送指令:' + hex + ";失败:" + JSON.stringify(res));
      }
    })

  }, _ServerConfigInfo.connectDelayed.writeData)
}

//将设备发的数据转换为16进制
function buf2hex(buffer) {
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('')
}

/**
 * 将Base64字符串转换成Byte数组
 * @return [0x00,0x00]
 * @param 字符串
 */
function base64_to_bytes_array(base64String) {
  var result = new Array();
  if (base64String.length % 4 != 0 || base64String.length == 0) {
    return result;
  }
  var b64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  // 先将后面的字段转换成原来的Byte数组
  var len = base64String.length;
  var endBytes = new Array();
  if (base64String.charAt(len - 1) == "=") {
    if (base64String.charAt(len - 2) == "=") { // 有两个等号的情况
      var s1 = base64String.charAt(len - 4); // 后面的第一个字符
      var s2 = base64String.charAt(len - 3); // 后面的第二个字符
      var v1 = ((b64Chars.indexOf(s1) << 2) & 0xFF) + (b64Chars.indexOf(s2) >> 4); //这个就是最后面的一个字节

      endBytes[0] = v1;
    } else { // 只有一个等号的情况
      var s1 = base64String.charAt(len - 4); // 后面的第一个字符
      var s2 = base64String.charAt(len - 3); // 后面的第二个字符
      var s3 = base64String.charAt(len - 2); // 后面的第三个字符

      var v1 = ((b64Chars.indexOf(s1) << 2) & 0xFF) + (b64Chars.indexOf(s2) >> 4); //这个就是最后面的第一个字节
      var v2 = ((b64Chars.indexOf(s2) << 4) & 0xFF) + (b64Chars.indexOf(s3) >> 2); //这个就是最后面的第二个字节

      endBytes[0] = v1;
      endBytes[1] = v2;
    }
  }

  var times = base64String.length / 4;

  for (var i = 0; i < times - (endBytes.length == 0 ? 0 : 1); i++) {
    var startIndex = i * 4;
    var V1 = base64String.charAt(startIndex + 0);
    var V2 = base64String.charAt(startIndex + 1);
    var V3 = base64String.charAt(startIndex + 2);
    var V4 = base64String.charAt(startIndex + 3);

    result[i * 3 + 0] = ((b64Chars.indexOf(V1) << 2) & 0xFF) + (b64Chars.indexOf(V2) >> 4);
    result[i * 3 + 1] = ((b64Chars.indexOf(V2) << 4) & 0xFF) + (b64Chars.indexOf(V3) >> 2);
    result[i * 3 + 2] = ((b64Chars.indexOf(V3) << 6) & 0xFF) + b64Chars.indexOf(V4);
  }
  return result.concat(endBytes);
}

/**
 * 把字节数组按16进制打印,这里需要保证数组的每个元素是Number类型
 * @param bytes
 */
function getHexBody(bytes) {
  var hexString = "Head:[";
  var len = 0;
  for (var i = 0; i < bytes.length; i++) {
    for (var i = 0; i < bytes.length; i++) {
      if (i === bytes.length - 1 || i === 23) hexString += (bytes[i] > 0xF ? bytes[i].toString(16) : "0" + bytes[i].toString(16));
      else hexString += (bytes[i] > 0xF ? bytes[i].toString(16) : "0" + bytes[i].toString(16)) + ",";
      if (i === 23) {
        hexString += "]<br/>Body:[";
        len = hexString.length;
      }
    }
  }
  console.log("hexbody-----" + hexString)
  hexString = hexString.substr(len);
  var hexArr = hexString.split(",");
  var result = "";
  for (var i = 0; i < hexArr.length; i++) {
    var tmp = '0x' + hexArr[i];
    result += String.fromCharCode(tmp);
  }
  return result;
}

//强制设置中转85指令为88
function transfer85To88() {

  //是否中转85开锁指令为88开锁指令
  _transferOpenLockCmd = true

  console.log("【85指令中转88指令】UI层强制中转85指令为88指令...")

}

function getDriverVersion() {
  return _driverVersion
}

//是否是旧固件驱动 true是,false不是
function isOldProcy() {
  return _RandomNumKey.length == 0;
}

function setParams(callback, that) {
  _Callback = callback;
  _that = that;
}

function getParams() {
  return {
    "callback": _Callback,
    "that": _that
  };
}

function setDevice(device) {
  _Device = device;
  getApp().globalData.conDevice = device;
}

function setWriteUuid(wuuid, wxsuuid) {
  _WXWriteUUID = wuuid;
  _WXServiceUUID = wxsuuid;
}

function recordBroadcastMac(devName, advertisData) {
  if (devName && advertisData) {
    let mac = devName.substring(2);
    let cacheStr = broadcastDevListCache[mac];
    if (cacheStr) {
      if (cacheStr == advertisData) {
        // console.log("mac="+mac+":广播没有变化！")
      } else {
        // console.log("mac=" + mac + ":[广播发生变化]", cacheStr, advertisData)//todolog
        //接收到的广播数据
        broadcastDevListCache[mac] = advertisData;
        broadcastDevList[mac] = advertisData;
      }
    } else {
      //接收到的广播数据
      broadcastDevListCache[mac] = advertisData;
      broadcastDevList[mac] = advertisData;
    }
  }
}

function isValidBTDeviceName(e) {
  return new RegExp("^DK.*$", "i").test(e);
}


function showDialog(i, status, t) {
  console.log("连接超时:", i)
  commonUtil.recordErrorInfo(ConstantData.err_type.ble_connect, "连接超时:" + i);
  a.globalData.connect_stat = 'fail';
  a.globalData.isConnecting = false;
  a.globalData.conErrDesc = i;
  stopTimeout();
  _that = _that ? _that : getApp().globalData._that;
  obBleUninstall(_that);
  if (arguments.length == 3) {
    statusChanged(status);
  } else {
    statusChanged(Status.bleConnectTimeout);
  }
}

function doConnection(that) {
  console.log(">>>>搜索到设备停止搜索>>>>")
  a.globalData.connect_stat = 'connecting';
  a.globalData.isConnecting = true;
  var e = that;
  wx.stopBluetoothDevicesDiscovery({
    success: function (e) {
      console.log(e);
    },
    complete: function (i) {
      console.log(i);
      if (i.errCode === 10000 && openAdapterCount > 0) {
        //上报搜索到的设备信息
        broadcastBack();
        //蓝牙适配器未初始化，重新初始化处理
        setTimeout(() => {
          console.warn("stopdiscover not init retry:", openAdapterCount);
          obBleInstall(that);
          openAdapterCount--;
        }, openAdapterTime * (3 - openAdapterCount));
      } else {
        broadcastBack('', 'con2');
      }
    }
  });
}

function connection(that) {

  a.globalData.consuc = false;
  console.log(">>>>开始连接>>>>")
  stopLocationAuthTimeout();
  stopOpenAdapterTimeout();
  var e = that;
  _that = that;
  setTimeout(function () {
    a.globalData.isConnecting = true;
    wx.onBLEConnectionStateChange(function (e) {
      getApp().globalData.devConnected = e ? e.connected : null;
      console.log("res.deviceId:[" + e.deviceId + "][" + e.connected + "]");
      a.globalData.BLEdeviceId = e.deviceId;
      console.log(a.globalData.BLEdeviceId, 'a.globalData.BLEdeviceId')
    });
    wx.createBLEConnection({
      deviceId: e.data.deviceId,
      timeout: _CreateConnectionTimeoutSize,
      success: function (i) {
        //连接成功的类型
        a.globalData.connectSucType = 'ble'  
        commonUtil.recordErrorInfo(ConstantData.err_type.ble_create_con_suc, "创建连接成功c");
        a.globalData.isConnecting = false;
        setTimeout(function () {
          wx.getBLEDeviceServices({
            deviceId: e.data.deviceId,
            success: function (i) {
              e.setData({
                services: i.services
              });
              for (var t = 0; t < i.services.length; t++)
                if (-1 != i.services[t].uuid.toUpperCase().indexOf("0000FEE7")) {
                  console.log("------getFEE7----->");
                  e.setData({
                    serviceId: e.data.services[t].uuid
                  });
                  break;
                }
              console.log("------START--getBLEDeviceCharacteristics----->");

              setTimeout(function () {
                wx.getBLEDeviceCharacteristics({
                  deviceId: e.data.deviceId,
                  serviceId: e.data.serviceId,
                  success: function (i) {
                    console.log("device getBLEDeviceCharacteristics:", i.characteristics);
                    let count = 0;
                    for (var t = 0; t < i.characteristics.length; t++) {
                      if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC8")) {
                        e.setData({
                          char6UUID: i.characteristics[t].uuid
                        });
                        count++;
                      } else if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC7")) {
                        setWriteUuid(i.characteristics[t].uuid, e.data.serviceId);
                        count++;
                      }
                      if (count == 2) {
                        break;
                      }
                    }
                    wx.notifyBLECharacteristicValueChanged({
                        deviceId: e.data.deviceId,
                        serviceId: e.data.serviceId,
                        characteristicId: e.data.char6UUID,
                        state: !0,
                        success: function (i) {
                          console.log('开启了通知3');
                          e.setData({
                            status: !0
                          });
                        },
                        fail: function (i) {
                          console.log("notifyBLECharacteristicValueChanged fail", i);
                          10005 === i.errCode && s >= 0 ? (getApp().hideLoading(),
                            obBleInstall(that)) : (e.setData({
                            status: !1
                          }), getApp().hideLoading(), showDialog("notifyBLECharacteristicValueChanged fail." + JSON.stringify(i), function () {}));
                        }
                      }),
                      //监听状态值变化
                      onBLECharacteristicValueChange();
                    a.globalData.connect_stat = 'success';
                  },
                  fail: function (i) {
                    if (i.errCode === 10005 && openAdapterCount > 0) {
                      getApp().hideLoading();
                      wx.closeBLEConnection({
                        deviceId: that.data.deviceId,
                        complete: function () {
                          obBleInstall(that);
                        }
                      });
                    } else {
                      console.log(i), showDialog("getBLEDeviceCharacteristics fail." + JSON.stringify(i), Status.bleConnectTimeout, function () {});
                    }
                  }
                });
              }, 10);
            },
            fail: function (i) {
              if (i.errCode === 10000 && openAdapterCount > 0) {
                //蓝牙适配器未初始化，重新初始化处理
                setTimeout(() => {
                  console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
                  obBleInstall(that);
                  openAdapterCount--;
                }, openAdapterTime * (3 - openAdapterCount));
              } else if (i.errCode === 10004 && openAdapterCount > 0) {
                //关闭连接重新连接尝试
                getApp().hideLoading();
                wx.closeBLEConnection({
                  deviceId: that.data.deviceId,
                  complete: function () {
                    obBleInstall(that);
                  }
                });
              } else {
                console.log(i), showDialog("getBLEDeviceServices fail." + JSON.stringify(i), function () {});
              }
            }
          });
        }, 50);
      },
      fail: function (i) {
        if (i.errCode === -1 && i.errMsg.indexOf("already connect") != -1) {
          //已经连接,重新开关蓝牙重试
          a.globalData.isConnecting = false;

          wx.onBLEConnectionStateChange(function (e) {
            console.log("res.deviceId:[" + e.deviceId + "][" + e.connected + "]");
            getApp().globalData.devConnected = e ? e.connected : null;
          }), setTimeout(function () {
            wx.getBLEDeviceServices({
              deviceId: e.data.deviceId,
              success: function (i) {
                e.setData({
                  services: i.services
                });
                for (var t = 0; t < i.services.length; t++)
                  if (-1 != i.services[t].uuid.toUpperCase().indexOf("0000FEE7")) {
                    console.log("------getFEE7----->");
                    e.setData({
                      serviceId: e.data.services[t].uuid
                    });
                    break;
                  }
                console.log("------START--getBLEDeviceCharacteristics----->");

                setTimeout(function () {
                  wx.getBLEDeviceCharacteristics({
                    deviceId: e.data.deviceId,
                    serviceId: e.data.serviceId,
                    success: function (i) {
                      console.log("device getBLEDeviceCharacteristics:", i.characteristics);
                      let count = 0;
                      for (var t = 0; t < i.characteristics.length; t++) {
                        if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC8")) {
                          e.setData({
                            char6UUID: i.characteristics[t].uuid
                          });
                          count++;
                        } else if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC7")) {
                          setWriteUuid(i.characteristics[t].uuid, e.data.serviceId);
                          count++;
                        }
                        if (count == 2) {
                          break;
                        }
                      }
                      wx.notifyBLECharacteristicValueChanged({
                          deviceId: e.data.deviceId,
                          serviceId: e.data.serviceId,
                          characteristicId: e.data.char6UUID,
                          state: !0,
                          success: function (i) {
                            console.warn('开启了通知4');
                            e.setData({
                              status: !0
                            });
                          },
                          fail: function (i) {
                            console.log("notifyBLECharacteristicValueChanged fail", i);
                            10005 === i.errCode && s >= 0 ? (getApp().hideLoading(),
                              obBleInstall(that)) : (e.setData({
                              status: !1
                            }), getApp().hideLoading(), showDialog("notifyBLECharacteristicValueChanged fail." + JSON.stringify(i), function () {}));
                          }
                        }),
                        //监听状态值变化
                        onBLECharacteristicValueChange();
                      a.globalData.connect_stat = 'success';
                    },
                    fail: function (i) {
                      if (i.errCode === 10005 && openAdapterCount > 0) {
                        getApp().hideLoading();
                        wx.closeBLEConnection({
                          deviceId: that.data.deviceId,
                          complete: function () {
                            obBleInstall(that);
                          }
                        });
                      } else {
                        console.log(i), showDialog("getBLEDeviceCharacteristics fail." + JSON.stringify(i), Status.bleConnectTimeout, function () {});
                      }
                    }
                  });
                }, 10);
              },
              fail: function (i) {
                if (i.errCode === 10000 && openAdapterCount > 0) {
                  //蓝牙适配器未初始化，重新初始化处理
                  setTimeout(() => {
                    console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
                    obBleInstall(that);
                    openAdapterCount--;
                  }, openAdapterTime * (3 - openAdapterCount));
                } else if (i.errCode === 10004 && openAdapterCount > 0) {
                  //关闭连接重新连接尝试
                  getApp().hideLoading();
                  wx.closeBLEConnection({
                    deviceId: that.data.deviceId,
                    complete: function () {
                      obBleInstall(that);
                    }
                  });
                } else {
                  console.log(i), showDialog("getBLEDeviceServices fail." + JSON.stringify(i), function () {});
                }
              }
            });
          }, 50);
        } else if (i.errCode === 10000 && openAdapterCount > 0) {
          //蓝牙适配器未初始化，重新初始化处理
          setTimeout(() => {
            console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
            obBleInstall(that);
            openAdapterCount--;
          }, openAdapterTime * (3 - openAdapterCount));
        } else {
          console.log(i);
          s -= 1;
          c += 500;
          if ((10006 === i.errCode || 10012 === i.errCode) && s >= 0) {
            setTimeout(function () {
              connection(that);
            }, c)
          } else if (10003 === i.errCode && s >= 0) {
            getApp().hideLoading();
            obBleInstall(that);
          } else if (10008 === i.errCode && s >= 0) {
            //系统错误重试连接
            getApp().hideLoading();
            wx.closeBLEConnection({
              deviceId: that.data.deviceId,
              complete: function () {
                obBleInstall(that);
              }
            });
          } else {
            getApp().hideLoading();
            showDialog("createBLEConnection fail:" + JSON.stringify(i), Status.bleConnectTimeout, function () {});
          }
        }
      }
    });
  }, 50);
}



function obBleUninstall(that) {
  console.log("*****uncon 1111*****");

  var e = that;
  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      console.log("stop discover suc", res);
    },
    fail: function (err) {
      console.log("----stop Fail---111", err)
    },
    complete: function (res) {
      console.log("----complate stop discovery--->", res)
    }
  });
  if (e && e.data && e.data.deviceId) {
    wx.closeBLEConnection({
      deviceId: e.data.deviceId,
      complete: function (res1) {
        console.log("closeBLEConnection", res1)
        e.setData({
          status: !1
        });
        wx.closeBluetoothAdapter({
          success: function (res) {
            console.log("closeBluetoothAdapter", res)
            _isOpenAdapterFlg = false
          },
        })
      }
    })
  }
}


function obBleInstall(that) {
  a.globalData.conErrDesc = '';
  console.log("--------->bleinstall>>>>>>>>>>>>>>>>>>");
  var e = that,
    curDevName = e.data.curDevName;
  let flg = true;
  startTimeout();
  startOpenAdapterTimeout();
  var isUseCacche = wx.getStorageSync('conIsUseCache');
  wx.openBluetoothAdapter({
    success: function (t) {
      _isOpenAdapterFlg = true;
      a.globalData.isConnecting = true;
      wx.removeStorageSync('retryOpenBlueAdapterCount');
      stopOpenAdapterTimeout();

      setTimeout(() => {

        wx.getBluetoothDevices({
          success: function (t) {
            console.log('getBluetoothDevices res =', t, "isCacche=" + isUseCacche);
            for (var n = 0;; n++) {
              if (n >= t.devices.length || !isUseCacche) {
                console.log("uniqueId:[" + curDevName + "] not cached"),
                  wx.startBluetoothDevicesDiscovery({
                    allowDuplicatesKey: !0,
                    powerLevel: 'high',
                    success: function (e) {
                      console.log(e);
                    },
                    fail: function (e) {
                      commonUtil.recordErrorInfo(ConstantData.err_type.connect_scan_fail, '没发现缓存,扫描失败:' + (e ? JSON.stringify(e) : 'null') + ";openAdpCount:" + openAdapterCount + ";isCache:" + isUseCacche);
                      if (e.errCode === 10000 && openAdapterCount > 0) {
                        //蓝牙适配器未初始化，重新初始化处理
                        setTimeout(() => {
                          console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
                          obBleInstall(that);
                          openAdapterCount--;
                        }, openAdapterTime * (3 - openAdapterCount));
                      } else {
                        stopLocationAuthTimeout();
                        showDialog("startBluetoothDevicesDiscovery fail:" + JSON.stringify(e), function () {});
                      }
                    }
                  });
                break;
              }
              var deviceId = t.devices[n].deviceId;

              let devName = null;
              if (t.devices[n].localName == null) {
                console.log('【匹配设备失败，设备的localName为空】');
              } else {
                devName = t.devices[n].localName;
              }
              if (t.devices[n].name == null && devName == null) {
                console.log('【匹配设备失败，设备的name为空】');
              } else {
                devName = t.devices[n].name;
              }

              if (devName && devName == e.data.curDevName) {
                e.setData({
                  deviceId: deviceId
                });


                setDevice(t.devices[n]);

                console.log("uniqueId:[" + curDevName + "] cached");
                if (flg) {
                  flg = false;
                  doConnection(that);
                  //通过缓存进行连接，如果连接超时，重试时直接开启扫描，重新扫描设备
                  _curConIsCache = true;
                }
                break;
              }
            }
          },
          fail: function (res) {
            that.recordBlueConnectError(ConstantData.err_type.connect_get_devs_fail, 'getBluetoothDevices fail:' + (res ? JSON.stringify(res) : 'null') + ";openCount:" + openAdapterCount);
            if (res.errCode === 10000 && openAdapterCount > 0) {
              //蓝牙适配器未初始化，重新初始化处理
              setTimeout(() => {
                console.warn("adapter not init retry ", openAdapterCount)
                obBleInstall(that);
                openAdapterCount--;
              }, openAdapterTime * (3 - openAdapterCount));
            } else {
              //蓝牙未打开请先打开蓝牙
              stopLocationAuthTimeout();
              showDialog("getBluetoothDevices fail:" + JSON.stringify(res), Status.bleConnectTimeout, function () {});
            }
          }
        });


      }, 300);


    },
    fail: function (i) {
      console.log('openBluetoothAdapter', i);
      that.recordBlueConnectError(ConstantData.err_type.connect_open_adpa_fail, 'openBluetoothAdapter fail:' + JSON.stringify(i));
      stopOpenAdapterTimeout();
      getApp().hideLoading();
      if (i.errCode === 10000 && openAdapterCount > 0) {
        //蓝牙适配器未初始化，重新初始化处理
        setTimeout(() => {
          console.warn("adapter fail not init retry ", openAdapterCount)
          obBleInstall(that);
          openAdapterCount--;
        }, openAdapterTime * (3 - openAdapterCount));
      } else {
        //蓝牙未打开请先打开蓝牙
        stopLocationAuthTimeout();
        if (i.errCode == 10001 || i.errMsg.indexOf('not available') != -1) {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(i), Status.bleIsClosed, function () {});
        } else {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(i), Status.adaperOpenFail, function () {});
        }
      }
    }
  });

  var startFoundTime = new Date().getTime();
  var foundTimeoutFlg = false;
  wx.onBluetoothDeviceFound(function (n) {
    stopLocationAuthTimeout();
    if (flg)
      for (var a = 0; a < n.devices.length; a++) {

        let devName = null;
        let advertisData = ab2hex(n.devices[a].advertisData);
        if (advertisData) {
          let head = advertisData.substring(0, 4);
          if (head > 5701) {
            let adMacName = advertisData.substring(4, 16);
            let dname = 'DK' + adMacName.toUpperCase();
            if (curDevName === dname) {
              devName = dname;
              console.log("--->adMac=", devName, 'advertisData=' + advertisData, n.devices[a]);
            }
          }
        }
        if (devName == null) {
          if (n.devices[a].localName == null) {
            console.log('【匹配设备失败，设备的localName为空】');
          } else {
            devName = n.devices[a].localName;
          }
          if (n.devices[a].name == null && devName == null) {
            console.log('【匹配设备失败，设备的name为空】');
          } else {
            devName = n.devices[a].name;
          }
        }

        if (isValidBTDeviceName(devName)) {
          recordBroadcastMac(devName, advertisData);
        }


        if (isValidBTDeviceName(devName) && curDevName === devName) {
          setDevice(n.devices[a]);
          var d = n.devices[a].deviceId;
          if (flg) {
            flg = false;
            e.setData({
              deviceId: d
            });
            console.log("get it:[" + d + "][" + curDevName + "]" + "[" + advertisData + "]");
            doConnection(that);
          };
          break;
        } else if (flg === !0) {
          let curTime = new Date().getTime();
          let diff = curTime - startFoundTime;
          let searchTimeout = 15000;
          if (that.data.curIsDirectCon) {
            searchTimeout = 10000;
          }
          if (diff > searchTimeout && !foundTimeoutFlg) {
            foundTimeoutFlg = true;
            flg = false;
            //超出搜索时长未搜索到设备
            wx.stopBluetoothDevicesDiscovery({
              success: function (res) {
                console.log("aaa stop discover suc", res);
              },
              fail: function (err) {
                console.log("aaa----stop Fail---111", err)
              },
              complete: function (res) {
                console.log("aaa----complate stop discovery--->", res)
                let rst = broadcastBack('', 'nocon');
                let bRst = rst ? rst : '';
                that.recordBlueConnectError(ConstantData.err_type.connect_scan_timeout, '搜索超时：deviceName=' + that.data.curDevName + ";scanTimeLen:" + diff);
                showDialog("搜索超时" + bRst, function () {});
              }
            });
            break;
          }
        }
      }
  });
}

//安卓直连
function directConnect(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  _that = that;
  that.data.stopConnect = false;
  that.setData({
    loading_show: true,
    loading_desc: '设备直连中'
  })
  //直连限制3秒
  getApp().globalData.directConnectTimer = setTimeout(() => {
    wx.setStorageSync('direct_con_forbidden', 1)
    that.recordBlueConnectError(ConstantData.err_type.connect_direct_timeout, 'direct connect timeout');

    //检查定位权限是否开启，如果开启走正常扫码流程，否则提示开启定位权限

   
  }, 3000);
  if (that.data.directFirstIsFail) {
    //直连失败，需要判断是否获取位置权限
    wx.getLocation({
      type: 'gcj02',
      complete: function (res) {
        console.warn('【-蓝牙直连-getLocation-res】', res);
        if (res.errMsg.indexOf('auth') != -1) {
          that.setData({
            loading_show: false,
            modal: {
              modal_show: true,
              title: '温馨提示',
              desc_mini: 'STO ' + that.data.pile_id + '(' + that.data.phoneInfo + '-100342)',
              desc: '为了您能正常使用，请您授权小程序位置权限',
              desc_center: true,
              openSetting: true
            }
          })
          that.recordBlueConnectError(40025, 'directConnect no location auth');
        } else if (res.errMsg.indexOf('system') != -1) {
          that.setData({
            loading_show: false,
            modal: {
              modal_show: true,
              title: '温馨提示',
              desc: '请打开定位和微信定位权限',
              icon_name: 'icon-dingwei',
              desc_mini: 'STO ' + that.data.pile_id + '(' + that.data.phoneInfo + '-100342)',
              desc_extra: '请根据图示检查定位权限配置',
              desc_center: true,
              open_location_show: true,
              retryConnect: true
            }
          })
          that.recordBlueConnectError(40025, 'directConnect no system location auth');
        } else {
          directConTimeoutSeconds = 10;
          timer_directCon_seconds = null;
          timer_directCon_seconds = setInterval(() => {
            if (directConTimeoutSeconds == 0) {
              clearInterval(timer_directCon_seconds);
              return;
            }
            directConTimeoutSeconds = directConTimeoutSeconds - 1;
          }, 1000)
          directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
        }
      }

    })
  } else {
    directConTimeoutSeconds = 15;
    timer_directCon_seconds = null;
    timer_directCon_seconds = setInterval(() => {
      if (directConTimeoutSeconds == 0) {
        clearInterval(timer_directCon_seconds);
        return;
      }
      directConTimeoutSeconds = directConTimeoutSeconds - 1;
    }, 1000)
    directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
  }

}

function directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  if (that.data.stopConnect) { //用户中断连接
    that.data.stopConnect = false;
    return;
  }
  wx.getConnectedBluetoothDevices({
    services: ['FEE7'],
    success: function (res) {
      console.warn('--连接中的设备', res);
      if (res.devices.length > 0) {
        return;
      } else {
        canDirectConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
      }
    },
    fail: function () {
      canDirectConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
    }
  })


}

function canDirectConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  that = that ? that : getApp().globalData._that;
  if (directConTimeoutSeconds == 0) {
    console.error("直连连接超时,请重试")
    //展示连接超时
    that.setData({
      loading_show: false,
      modal: {
        modal_show: true,
        desc: '连接超时，请关闭蓝牙再打开后重试(Z' + getApp().globalData.curConHid + ')',
        confirm: true
      }
    })
    stopTimeout();
    that.recordBlueConnectError(40011, 'directConnect Timeout');
    return;
  }
  console.warn("----start connect-------<>----####", deviceName);
  //生产检测使用
  getApp().globalData.mac = deviceName ? deviceName.replace("DK", "") : '';
  obBleUninstall(that);
  that.data.curDevName = deviceName;
  setParams(statusCallback, that);
  openAdapterCount = 3;
  s = 3;

  _WXWriteUUID = '0000FEC7-0000-1000-8000-00805F9B34FB';
  _WXServiceUUID = '0000FEE7-0000-1000-8000-00805F9B34FB';
  var devId = that.data.wxDeviceId;
  _Device = {};
  _Device.deviceId = devId;
  console.log("device-->", _Device);

  wx.openBluetoothAdapter({
    success: function (res) {
      a.globalData.isConnecting = true;
      wx.removeStorageSync('retryOpenBlueAdapterCount');
      startDiscovery(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
    },
    fail: function (res) {
      that.recordBlueConnectError(40020, 'directConnect openBluetoothAdapter fail:' + JSON.stringify(res));
      if (res.errCode == 10001 || res.errMsg.indexOf('not available') != -1) {
        showDialog("openBluetoothAdapter fail:" + JSON.stringify(res), Status.bleIsClosed, function () {});
      } else {
        that.data.directFirstIsFail = true;
        directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }
    }
  })
}

function startDiscovery(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  var devId = that.data.wxDeviceId;
  console.log("直连的设备id--->", devId)
  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: true,
    powerLevel: 'high',
    success: function (res) {
      console.log(res, 'startBluetoothDevicesDiscovery')
      setTimeout(function () {
        wx.stopBluetoothDevicesDiscovery({
          success: function (res) {},
          complete: function (res) {

            //直接连接
            wx.createBLEConnection({
              // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
              deviceId: devId,
              timeout: _CreateConnectionTimeoutSize,
              success(res) {
                if (getApp().globalData.directConnectTimer) {
                  clearTimeout(getApp().globalData.directConnectTimer);
                }
                //连接成功的类型
                getApp().globalData.connectSucType = 'ble'
                commonUtil.recordErrorInfo(ConstantData.err_type.ble_create_con_suc, "创建连接成功d");
                console.log(res);
                a.globalData.isConnecting = false;
                notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
              },
              fail: function (res) {
                console.log("createCon", res)
                a.globalData.isConnecting = false;
                that.recordBlueConnectError(40020, 'directConnect createBLEConnection fail' + JSON.stringify(res));
                if (res.errMsg.indexOf('deviceId') != -1) {
                  that.setData({
                    loading_show: false,
                    modal: {
                      modal_show: true,
                      desc: '连接失败，请扫码重试',
                      confirm: true
                    }
                  })
                  return;
                } else if (res.errCode == -1 && res.errMsg.indexOf('already connect') != -1) {
                  notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
                  return;
                } else {
                  that.data.directFirstIsFail = true;
                  directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
                }
              }
            })

          },
          fail: function (res) {
            that.recordBlueConnectError(40020, 'directConnect stopBluetoothDevicesDiscovery fail' + JSON.stringify(res));
          }
        });
      }, 2370)
    },
    fail: function (res) {
      that.recordBlueConnectError(40020, 'directConnect startBluetoothDevicesDiscovery' + JSON.stringify(res));
      if (res.errCode === 10000 && directConTimeoutSeconds > 0) {
        //蓝牙适配器未初始化，延时搜索
        setTimeout(() => {
          console.warn("adapter not init retry ");
          startDiscovery(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
        }, 300);
      } else {
        //再重连直到15秒超时
        that.data.directFirstIsFail = true;
        directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }
    }
  });
}

function notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  var devId = that.data.wxDeviceId;
  wx.notifyBLECharacteristicValueChange({
    state: true, // 启用 notify 功能
    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
    deviceId: devId,
    // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
    serviceId: '0000FEE7-0000-1000-8000-00805F9B34FB',
    // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
    characteristicId: '0000FEC8-0000-1000-8000-00805F9B34FB',
    success(res) {
      console.warn('开启了通知1');
      console.log('notifyBLECharacteristicValueChange success', res.errMsg)
    },
    complete: function (res) {
      onBLECharacteristicValueChange();
    },
    fail: function (res) {
      that.recordBlueConnectError(40020, 'directConnect notifyBLECharacteristicValueChange fail' + JSON.stringify(res));
      if (res.errCode === 10000 && directConTimeoutSeconds > 0) {
        //蓝牙适配器未初始化，延时搜索
        setTimeout(() => {
          console.warn("adapter not init retry ");
          notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
        }, 300);
      } else {
        //再重连直到15秒超时
        that.data.directFirstIsFail = true;
        directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }
    }
  })
}

function newConnect(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  console.log("----start connect-------<>----####", deviceName)
  that = that ? that : getApp().globalData._that;
  obBleUninstall(that);
  console.log("*****con 1111*****");
  that.data.curDevName = deviceName;
  let mac = deviceName ? deviceName.replace('DK', '') : '';
  that.data.mac = mac;
  getApp().globalData.mac = mac;
  console.log("*****con 2222*****");
  console.log("*****con 3333*****");
  setParams(statusCallback, that);
  console.log("*****con 4444*****");
  openAdapterCount = 3;
  s = 3;
  obBleInstall(that);
}

function Bytes2HexString(arrBytes) {
  var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  for (var n = [], r = 0; r < t.length; r++) n.push((t[r] >>> 4).toString(16)), n.push((15 & t[r]).toString(16));
  return n.join("");
}


module.exports.newConnect = newConnect
module.exports.directConnect = directConnect

module.exports.broadcastBack = broadcastBack
module.exports.recordBroadcastMac = recordBroadcastMac
module.exports.setWriteUuid = setWriteUuid
module.exports.setDevice = setDevice
module.exports.setParams = setParams
module.exports.getParams = getParams
module.exports.Status = Status
module.exports.connect = connect
module.exports.disconnect = disconnect
module.exports.sendBroadcastConfCommand = sendBroadcastConfCommand
module.exports.send85Command = send85Command
module.exports.send1301Command = send1301Command
module.exports.send95Command = send95Command
module.exports.send75Command = send75Command
module.exports.send76Command = send76Command
module.exports.send98Command = send98Command
module.exports.sendB0Command = sendB0Command
module.exports.send90Command = send90Command
module.exports.sendBaseCommand = sendBaseCommand
module.exports.setErrorCallback = setErrorCallback
module.exports.setConnectLogCall = setConnectLogCall
module.exports.setServerConfigInfo = setServerConfigInfo
module.exports.setConnectiTimeOut = setConnectiTimeOut
module.exports.setHomingDeviceServiceInfo = setHomingDeviceServiceInfo
module.exports.setCollectionServiceData = setCollectionServiceData
module.exports.transfer85To88 = transfer85To88
module.exports.getDriverVersion = getDriverVersion
module.exports.findDevStopDiscovery = findDevStopDiscovery
module.exports.scanBox = scanBox
module.exports.onBLECharacteristicValueChange = onBLECharacteristicValueChange
module.exports.ab2hex = ab2hex
module.exports.statusChanged = statusChanged
module.exports.startTimeout = startTimeout
module.exports.stopTimeout = stopTimeout
module.exports.handleDeviceData = handleDeviceData
module.exports.setIsOpenAdapterFlg = setIsOpenAdapterFlg
module.exports.stop85Back1Timeout = stop85Back1Timeout
module.exports.stop85Back2Timeout = stop85Back2Timeout
module.exports.sendPeiHuYiBleGetToken = sendPeiHuYiBleGetToken
module.exports.oneMorePhyBleUnlock = oneMorePhyBleUnlock
module.exports.oneMorePhyBleLock = oneMorePhyBleLock